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 \ ...@@ -62,10 +62,16 @@ SOURCES_atmo = atmo/atmo.cpp \
atmo/AtmoInput.cpp atmo/AtmoInput.h \ atmo/AtmoInput.cpp atmo/AtmoInput.h \
atmo/AtmoLiveView.cpp atmo/AtmoLiveView.h \ atmo/AtmoLiveView.cpp atmo/AtmoLiveView.h \
atmo/AtmoOutputFilter.cpp atmo/AtmoOutputFilter.h \ atmo/AtmoOutputFilter.cpp atmo/AtmoOutputFilter.h \
atmo/AtmoSerialConnection.cpp atmo/AtmoSerialConnection.h \
atmo/AtmoThread.cpp atmo/AtmoThread.h \ atmo/AtmoThread.cpp atmo/AtmoThread.h \
atmo/AtmoTools.cpp atmo/AtmoTools.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 SOURCES_video_filter_wrapper = wrapper.c
noinst_HEADERS = filter_common.h filter_picture.h noinst_HEADERS = filter_common.h filter_picture.h
......
...@@ -13,8 +13,52 @@ ...@@ -13,8 +13,52 @@
#include "AtmoDefs.h" #include "AtmoDefs.h"
#include "AtmoConfig.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); tHSVColor RGB2HSV(tRGBColor color);
tRGBColor HSV2RGB(tHSVColor 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 @@ ...@@ -9,8 +9,11 @@
#include "AtmoDefs.h" #include "AtmoDefs.h"
#include "AtmoSerialConnection.h" #include "AtmoClassicConnection.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoClassicConfigDialog.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -20,25 +23,15 @@ ...@@ -20,25 +23,15 @@
#include <unistd.h> #include <unistd.h>
#endif #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; m_hComport = INVALID_HANDLE_VALUE;
} }
CAtmoSerialConnection::~CAtmoSerialConnection() { CAtmoClassicConnection::~CAtmoClassicConnection() {
CloseConnection();
} }
ATMO_BOOL CAtmoSerialConnection::OpenConnection() { ATMO_BOOL CAtmoClassicConnection::OpenConnection() {
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
char *serdevice = m_pAtmoConfig->getSerialDevice(); char *serdevice = m_pAtmoConfig->getSerialDevice();
if(!serdevice) if(!serdevice)
...@@ -52,24 +45,20 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() { ...@@ -52,24 +45,20 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() {
CloseConnection(); CloseConnection();
#if !defined(_ATMO_VLC_PLUGIN_) #if !defined(_ATMO_VLC_PLUGIN_)
char comport[16]; // com4294967295 char serdevice[16]; // com4294967295
sprintf(comport,"com%d",portNummer); sprintf(serdevice,"com%d",portNummer);
#endif #endif
#if defined(WIN32) #if defined(WIN32)
# if defined(_ATMO_VLC_PLUGIN_)
m_hComport = CreateFile(serdevice, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 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) { if(m_hComport == INVALID_HANDLE_VALUE) {
// we have a problem here can't open com port... somebody else may use it? // we have a problem here can't open com port... somebody else may use it?
// m_dwLastWin32Error = GetLastError(); // m_dwLastWin32Error = GetLastError();
return ATMO_FALSE; return ATMO_FALSE;
} }
/* change serial settings (Speed, stopbits etc.) */ /* change serial settings (Speed, stopbits etc.) */
DCB dcb; // für comport-parameter DCB dcb; // fr comport-parameter
dcb.DCBlength = sizeof(DCB); dcb.DCBlength = sizeof(DCB);
GetCommState (m_hComport, &dcb); // ger current serialport settings GetCommState (m_hComport, &dcb); // ger current serialport settings
dcb.BaudRate = 38400; // set speed dcb.BaudRate = 38400; // set speed
...@@ -81,11 +70,7 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() { ...@@ -81,11 +70,7 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() {
#else #else
int bconst = B38400; int bconst = B38400;
# if defined(_ATMO_VLC_PLUGIN_)
m_hComport = open(serdevice,O_RDWR |O_NOCTTY); m_hComport = open(serdevice,O_RDWR |O_NOCTTY);
# else
m_hComport = open(comport,O_RDWR | O_NOCTTY);
# endif
if(m_hComport < 0) { if(m_hComport < 0) {
return ATMO_FALSE; return ATMO_FALSE;
} }
...@@ -110,7 +95,7 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() { ...@@ -110,7 +95,7 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() {
return true; return true;
} }
void CAtmoSerialConnection::CloseConnection() { void CAtmoClassicConnection::CloseConnection() {
if(m_hComport!=INVALID_HANDLE_VALUE) { if(m_hComport!=INVALID_HANDLE_VALUE) {
#if defined(WIN32) #if defined(WIN32)
CloseHandle(m_hComport); CloseHandle(m_hComport);
...@@ -121,11 +106,11 @@ void CAtmoSerialConnection::CloseConnection() { ...@@ -121,11 +106,11 @@ void CAtmoSerialConnection::CloseConnection() {
} }
} }
ATMO_BOOL CAtmoSerialConnection::isOpen(void) { ATMO_BOOL CAtmoClassicConnection::isOpen(void) {
return (m_hComport != INVALID_HANDLE_VALUE); return (m_hComport != INVALID_HANDLE_VALUE);
} }
ATMO_BOOL CAtmoSerialConnection::HardwareWhiteAdjust(int global_gamma, ATMO_BOOL CAtmoClassicConnection::HardwareWhiteAdjust(int global_gamma,
int global_contrast, int global_contrast,
int contrast_red, int contrast_red,
int contrast_green, int contrast_green,
...@@ -193,7 +178,7 @@ ATMO_BOOL CAtmoSerialConnection::HardwareWhiteAdjust(int global_gamma, ...@@ -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) if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE; return ATMO_FALSE;
...@@ -205,11 +190,19 @@ ATMO_BOOL CAtmoSerialConnection::SendData(tColorPacket data) { ...@@ -205,11 +190,19 @@ ATMO_BOOL CAtmoSerialConnection::SendData(tColorPacket data) {
buffer[2] = 0x00; // Start channel 0 buffer[2] = 0x00; // Start channel 0
buffer[3] = 15; // buffer[3] = 15; //
int iBuffer = 4; int iBuffer = 4;
for(int i=0;i<5;i++) { int idx;
if(m_ChannelAssignment[i]>=0) {
buffer[iBuffer++] = data.channel[m_ChannelAssignment[i]].r; Lock();
buffer[iBuffer++] = data.channel[m_ChannelAssignment[i]].g;
buffer[iBuffer++] = data.channel[m_ChannelAssignment[i]].b; 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 { } else {
buffer[iBuffer++] = 0; buffer[iBuffer++] = 0;
buffer[iBuffer++] = 0; buffer[iBuffer++] = 0;
...@@ -224,47 +217,67 @@ ATMO_BOOL CAtmoSerialConnection::SendData(tColorPacket data) { ...@@ -224,47 +217,67 @@ ATMO_BOOL CAtmoSerialConnection::SendData(tColorPacket data) {
tcdrain(m_hComport); tcdrain(m_hComport);
#endif #endif
Unlock();
return (iBytesWritten == 19) ? ATMO_TRUE : ATMO_FALSE; return (iBytesWritten == 19) ? ATMO_TRUE : ATMO_FALSE;
} }
ATMO_BOOL CAtmoSerialConnection::SendData(unsigned char numChannels,
int red[], ATMO_BOOL CAtmoClassicConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
int green[],
int blue[])
{ {
if(m_hComport == INVALID_HANDLE_VALUE) if(!ca) return ATMO_FALSE;
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; #if !defined(_ATMO_VLC_PLUGIN_)
unsigned char *buffer = new unsigned char[bufSize];
DWORD iBytesWritten;
buffer[0] = 0xFF; // Start Byte char *CAtmoClassicConnection::getChannelName(int ch)
buffer[1] = 0x00; // Start Kanal 0 {
buffer[2] = 0x00; // Start Kanal 0 if(ch < 0) return NULL;
buffer[3] = numChannels * 3; // char buf[30];
int iBuffer = 4;
for(int i=0;i<numChannels;i++) { switch(ch) {
if(m_ChannelAssignment[i]>=0) { case 0:
buffer[iBuffer++] = red[m_ChannelAssignment[i]] & 255; sprintf(buf,"Summen Kanal [%d]",ch);
buffer[iBuffer++] = green[m_ChannelAssignment[i]] & 255; break;
buffer[iBuffer++] = blue[m_ChannelAssignment[i]] & 255; case 1:
} else { sprintf(buf,"Linker Kanal [%d]",ch);
buffer[iBuffer++] = 0; break;
buffer[iBuffer++] = 0; case 2:
buffer[iBuffer++] = 0; 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) return strdup(buf);
WriteFile(m_hComport, buffer, bufSize, &iBytesWritten, NULL); }
#else
iBytesWritten = write(m_hComport, buffer, bufSize); ATMO_BOOL CAtmoClassicConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
tcdrain(m_hComport); {
#endif 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 @@ ...@@ -6,8 +6,8 @@
* *
* $Id$ * $Id$
*/ */
#ifndef _AtmoSerialConnection_h_ #ifndef _AtmoClassicConnection_h_
#define _AtmoSerialConnection_h_ #define _AtmoClassicConnection_h_
#include "AtmoDefs.h" #include "AtmoDefs.h"
#include "AtmoConnection.h" #include "AtmoConnection.h"
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#endif #endif
class CAtmoSerialConnection : public CAtmoConnection { class CAtmoClassicConnection : public CAtmoConnection {
private: private:
HANDLE m_hComport; HANDLE m_hComport;
...@@ -29,8 +29,8 @@ class CAtmoSerialConnection : public CAtmoConnection { ...@@ -29,8 +29,8 @@ class CAtmoSerialConnection : public CAtmoConnection {
#endif #endif
public: public:
CAtmoSerialConnection(CAtmoConfig *cfg); CAtmoClassicConnection(CAtmoConfig *cfg);
virtual ~CAtmoSerialConnection(void); virtual ~CAtmoClassicConnection(void);
virtual ATMO_BOOL OpenConnection(); virtual ATMO_BOOL OpenConnection();
...@@ -38,12 +38,7 @@ class CAtmoSerialConnection : public CAtmoConnection { ...@@ -38,12 +38,7 @@ class CAtmoSerialConnection : public CAtmoConnection {
virtual ATMO_BOOL isOpen(void); virtual ATMO_BOOL isOpen(void);
virtual ATMO_BOOL SendData(unsigned char numChannels, virtual ATMO_BOOL SendData(pColorPacket data);
int red[],
int green[],
int blue[]);
virtual ATMO_BOOL SendData(tColorPacket data);
virtual ATMO_BOOL HardwareWhiteAdjust(int global_gamma, virtual ATMO_BOOL HardwareWhiteAdjust(int global_gamma,
int global_contrast, int global_contrast,
...@@ -54,6 +49,18 @@ class CAtmoSerialConnection : public CAtmoConnection { ...@@ -54,6 +49,18 @@ class CAtmoSerialConnection : public CAtmoConnection {
int gamma_green, int gamma_green,
int gamma_blue, int gamma_blue,
ATMO_BOOL storeToEeprom); 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 #endif
This diff is collapsed.
...@@ -9,11 +9,13 @@ ...@@ -9,11 +9,13 @@
#ifndef _AtmoConfig_h_ #ifndef _AtmoConfig_h_
#define _AtmoConfig_h_ #define _AtmoConfig_h_
#include <stdlib.h>
#include "AtmoDefs.h" #include "AtmoDefs.h"
#include "AtmoZoneDefinition.h" #include "AtmoZoneDefinition.h"
#include "AtmoChannelAssignment.h"
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
# include <stdlib.h>
# include <string.h> # include <string.h>
#endif #endif
...@@ -24,12 +26,16 @@ class CAtmoConfig { ...@@ -24,12 +26,16 @@ class CAtmoConfig {
int m_IsShowConfigDialog; int m_IsShowConfigDialog;
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
char *m_devicename; char *m_devicename;
char *m_devicenames[3]; // additional Devices ?
#else #else
int m_Comport; int m_Comport;
int m_Comports[3]; // additional Comports
#endif #endif
enum AtmoConnectionType m_eAtmoConnectionType; enum AtmoConnectionType m_eAtmoConnectionType;
enum EffectMode m_eEffectMode; enum EffectMode m_eEffectMode;
ATMO_BOOL m_IgnoreConnectionErrorOnStartup;
protected: protected:
ATMO_BOOL m_UseSoftwareWhiteAdj; ATMO_BOOL m_UseSoftwareWhiteAdj;
int m_WhiteAdjustment_Red; int m_WhiteAdjustment_Red;
...@@ -63,11 +69,30 @@ class CAtmoConfig { ...@@ -63,11 +69,30 @@ class CAtmoConfig {
one for System + 9 for userdefined channel one for System + 9 for userdefined channel
assignments (will it be enough?) assignments (will it be enough?)
*/ */
tChannelAssignment *m_ChannelAssignments[10]; CAtmoChannelAssignment *m_ChannelAssignments[10];
int m_CurrentChannelAssignment; int m_CurrentChannelAssignment;
protected: 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: protected:
...@@ -77,6 +102,8 @@ class CAtmoConfig { ...@@ -77,6 +102,8 @@ class CAtmoConfig {
int m_LiveViewFilter_MeanLength; int m_LiveViewFilter_MeanLength;
int m_LiveViewFilter_MeanThreshold; int m_LiveViewFilter_MeanThreshold;
ATMO_BOOL m_show_statistics;
// weighting of distance to edge // weighting of distance to edge
int m_LiveView_EdgeWeighting; // = 8; int m_LiveView_EdgeWeighting; // = 8;
// brightness correction // brightness correction
...@@ -107,6 +134,8 @@ class CAtmoConfig { ...@@ -107,6 +134,8 @@ class CAtmoConfig {
*/ */
int m_LiveView_FrameDelay; int m_LiveView_FrameDelay;
int m_LiveView_GDI_FrameRate;
protected: protected:
/* values of the last hardware white adjustment (only for hardware with new firmware) */ /* values of the last hardware white adjustment (only for hardware with new firmware) */
int m_Hardware_global_gamma; int m_Hardware_global_gamma;
...@@ -118,6 +147,25 @@ class CAtmoConfig { ...@@ -118,6 +147,25 @@ class CAtmoConfig {
int m_Hardware_gamma_green; int m_Hardware_gamma_green;
int m_Hardware_gamma_blue; 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: public:
CAtmoConfig(); CAtmoConfig();
virtual ~CAtmoConfig(); virtual ~CAtmoConfig();
...@@ -132,18 +180,27 @@ class CAtmoConfig { ...@@ -132,18 +180,27 @@ class CAtmoConfig {
*/ */
void Assign(CAtmoConfig *pAtmoConfigSrc); void Assign(CAtmoConfig *pAtmoConfigSrc);
void UpdateZoneDefinitionCount();
public: public:
int isShowConfigDialog() { return m_IsShowConfigDialog; } int isShowConfigDialog() { return m_IsShowConfigDialog; }
void setShowConfigDialog(int value) { m_IsShowConfigDialog = value; } void setShowConfigDialog(int value) { m_IsShowConfigDialog = value; }
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
char *getSerialDevice() { return m_devicename; } 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 #else
int getComport() { return m_Comport; } int getComport() { return m_Comport; }
void setComport(int value) { m_Comport = value; } void setComport(int value) { m_Comport = value; }
int getComport(int i);
void setComport(int i, int nr);
#endif #endif
ATMO_BOOL getIgnoreConnectionErrorOnStartup() { return m_IgnoreConnectionErrorOnStartup; }
void setIgnoreConnectionErrorOnStartup(ATMO_BOOL ignore) { m_IgnoreConnectionErrorOnStartup = ignore; }
int getWhiteAdjustment_Red() { return m_WhiteAdjustment_Red; } int getWhiteAdjustment_Red() { return m_WhiteAdjustment_Red; }
void setWhiteAdjustment_Red(int value) { m_WhiteAdjustment_Red = value; } void setWhiteAdjustment_Red(int value) { m_WhiteAdjustment_Red = value; }
int getWhiteAdjustment_Green() { return m_WhiteAdjustment_Green; } int getWhiteAdjustment_Green() { return m_WhiteAdjustment_Green; }
...@@ -186,6 +243,8 @@ class CAtmoConfig { ...@@ -186,6 +243,8 @@ class CAtmoConfig {
EffectMode getEffectMode() { return m_eEffectMode; } EffectMode getEffectMode() { return m_eEffectMode; }
void setEffectMode(EffectMode value) { m_eEffectMode = value; } void setEffectMode(EffectMode value) { m_eEffectMode = value; }
ATMO_BOOL getShow_statistics() { return m_show_statistics; }
AtmoFilterMode getLiveViewFilterMode() { return m_LiveViewFilterMode; } AtmoFilterMode getLiveViewFilterMode() { return m_LiveViewFilterMode; }
void setLiveViewFilterMode(AtmoFilterMode value) { m_LiveViewFilterMode = value; } void setLiveViewFilterMode(AtmoFilterMode value) { m_LiveViewFilterMode = value; }
...@@ -226,6 +285,9 @@ class CAtmoConfig { ...@@ -226,6 +285,9 @@ class CAtmoConfig {
int getLiveView_FrameDelay() { return m_LiveView_FrameDelay; } int getLiveView_FrameDelay() { return m_LiveView_FrameDelay; }
void setLiveView_FrameDelay(int delay) { m_LiveView_FrameDelay = delay; } 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 ; } int getHardware_global_gamma() { return m_Hardware_global_gamma ; }
void setHardware_global_gamma(int value) { m_Hardware_global_gamma=value; } void setHardware_global_gamma(int value) { m_Hardware_global_gamma=value; }
...@@ -250,7 +312,20 @@ class CAtmoConfig { ...@@ -250,7 +312,20 @@ class CAtmoConfig {
int getHardware_gamma_blue() { return m_Hardware_gamma_blue; } int getHardware_gamma_blue() { return m_Hardware_gamma_blue; }
void setHardware_gamma_blue(int value) { m_Hardware_gamma_blue=value; } 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]; return this->m_ChannelAssignments[nummer];
} }
int getCurrentChannelAssignment() { return m_CurrentChannelAssignment; } int getCurrentChannelAssignment() { return m_CurrentChannelAssignment; }
...@@ -259,11 +334,31 @@ class CAtmoConfig { ...@@ -259,11 +334,31 @@ class CAtmoConfig {
int getNumChannelAssignments(); int getNumChannelAssignments();
void clearChannelMappings(); void clearChannelMappings();
void clearAllChannelMappings(); void clearAllChannelMappings();
void AddChannelAssignment(tChannelAssignment *ta); void AddChannelAssignment(CAtmoChannelAssignment *ta);
void SetChannelAssignment(int index, tChannelAssignment *ta); void SetChannelAssignment(int index, CAtmoChannelAssignment *ta);
CAtmoZoneDefinition *getZoneDefinition(int zoneIndex); 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 #endif
...@@ -6,31 +6,68 @@ ...@@ -6,31 +6,68 @@
* *
* $Id$ * $Id$
*/ */
#include <string.h>
#include "AtmoConnection.h" #include "AtmoConnection.h"
CAtmoConnection::CAtmoConnection(CAtmoConfig *cfg) CAtmoConnection::CAtmoConnection(CAtmoConfig *cfg)
{ {
this->m_pAtmoConfig = cfg; this->m_pAtmoConfig = cfg;
if(cfg->getNumChannelAssignments()>0) { m_ChannelAssignment = NULL;
tChannelAssignment *ca = cfg->getChannelAssignment(0); m_NumAssignedChannels = 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) { #if defined(_ATMO_VLC_PLUGIN_)
for(int i=0;i<ATMO_NUM_CHANNELS;i++) { vlc_mutex_init( &m_AccessConnection );
m_ChannelAssignment[i] = ca->mappings[i]; #else
} InitializeCriticalSection( &m_AccessConnection );
#endif
} }
CAtmoConnection::~CAtmoConnection(void) CAtmoConnection::~CAtmoConnection(void)
{ {
if(isOpen()) if(isOpen())
CloseConnection(); 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 @@ ...@@ -9,14 +9,36 @@
#ifndef _AtmoConnection_h_ #ifndef _AtmoConnection_h_
#define _AtmoConnection_h_ #define _AtmoConnection_h_
#include <stdlib.h>
#include "AtmoDefs.h" #include "AtmoDefs.h"
#include "AtmoConfig.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 class CAtmoConnection
{ {
protected: protected:
CAtmoConfig *m_pAtmoConfig; 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: public:
CAtmoConnection(CAtmoConfig *cfg); CAtmoConnection(CAtmoConfig *cfg);
...@@ -25,12 +47,7 @@ public: ...@@ -25,12 +47,7 @@ public:
virtual void CloseConnection() {}; virtual void CloseConnection() {};
virtual ATMO_BOOL isOpen(void) { return false; } virtual ATMO_BOOL isOpen(void) { return false; }
virtual ATMO_BOOL SendData(unsigned char numChannels, virtual ATMO_BOOL SendData(pColorPacket data) { return false; }
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 setChannelColor(int channel, tRGBColor color) { return false; }
virtual ATMO_BOOL setChannelValues(int numValues,unsigned char *channel_values) { return false; } virtual ATMO_BOOL setChannelValues(int numValues,unsigned char *channel_values) { return false; }
...@@ -45,7 +62,18 @@ public: ...@@ -45,7 +62,18 @@ public:
int gamma_blue, int gamma_blue,
ATMO_BOOL storeToEeprom) { return false; } 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 @@ ...@@ -10,36 +10,47 @@
#ifndef _AtmoDefs_h_ #ifndef _AtmoDefs_h_
#define _AtmoDefs_h_ #define _AtmoDefs_h_
#if defined(__LIBVLC__)
# include "config.h"
# define __STDC_CONSTANT_MACROS 1 #if defined(__LIBVLC__)
# include <inttypes.h>
# 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 */ /* some things need to be changed if this code is used inside VideoLan Filter Module */
# define _ATMO_VLC_PLUGIN_ # define _ATMO_VLC_PLUGIN_
# define ATMO_BOOL bool # define get_time mdate()
# define ATMO_TRUE true # define do_sleep(a) msleep(a)
# define ATMO_FALSE false
#else #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) | \ # define MakeDword(ch1,ch2,ch3,ch4) ((((DWORD)(ch1)&255) << 24) | \
(((DWORD)(ch2)&255) << 16) | \ (((DWORD)(ch2)&255) << 16) | \
(((DWORD)(ch3)&255) << 8) | \ (((DWORD)(ch3)&255) << 8) | \
(((DWORD)(ch4)&255))) (((DWORD)(ch4)&255)))
# define get_time GetTickCount()
# define do_sleep(a) Sleep(a)
#endif #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) #if !defined(WIN32)
...@@ -68,33 +79,54 @@ typedef struct ...@@ -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
#ifdef CAP_16x9
// maximal Anzahl Kanäle... # define CAP_WIDTH 88
#define ATMO_NUM_CHANNELS 5 # define CAP_HEIGHT 48
#else
// capture width/height # define CAP_WIDTH 64
#define CAP_WIDTH 64 # define CAP_HEIGHT 48
#define CAP_HEIGHT 48 #endif
// imagesize // imagesize
#define IMAGE_SIZE (CAP_WIDTH * CAP_HEIGHT) #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 enum AtmoConnectionType
{ {
actSerialPort = 0, actClassicAtmo = 0,
actDummy = 1, actDummy = 1,
actDMX = 2 actDMX = 2,
actNUL = 3,
actMultiAtmo = 4,
actMondolight = 5,
actMoMoLight = 6
}; };
static const char *AtmoDeviceTypes[] = { static const char *AtmoDeviceTypes[] = {
"Atmo", "Atmo-Classic",
"Dummy", "Dummy",
"DMX" "DMX",
"Nul-Device",
"Multi-Atmo",
"Mondolight",
"MoMoLight"
}; };
#define ATMO_DEVICE_COUNT 3 #define ATMO_DEVICE_COUNT 7
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
enum EffectMode { enum EffectMode {
...@@ -103,7 +135,14 @@ enum EffectMode { ...@@ -103,7 +135,14 @@ enum EffectMode {
emStaticColor = 1, emStaticColor = 1,
emLivePicture = 2 emLivePicture = 2
}; };
enum LivePictureSource {
lpsDisabled = 0,
lpsExtern = 2
};
#else #else
enum EffectMode { enum EffectMode {
emUndefined = -1, emUndefined = -1,
emDisabled = 0, emDisabled = 0,
...@@ -112,10 +151,20 @@ enum EffectMode { ...@@ -112,10 +151,20 @@ enum EffectMode {
emColorChange = 3, emColorChange = 3,
emLrColorChange = 4 emLrColorChange = 4
}; };
#endif
enum LivePictureSource {
lpsDisabled = 0,
lpsScreenCapture = 1,
lpsExtern = 2
};
#endif
enum AtmoGammaCorrect {
agcNone = 0,
agcPerColor = 1,
agcGlobal = 2
};
enum AtmoFilterMode { enum AtmoFilterMode {
afmNoFilter, afmNoFilter,
...@@ -123,12 +172,6 @@ enum AtmoFilterMode { ...@@ -123,12 +172,6 @@ enum AtmoFilterMode {
afmPercent afmPercent
}; };
typedef struct {
ATMO_BOOL system;
char name[64];
int mappings[ATMO_NUM_CHANNELS];
} tChannelAssignment;
// --- tRGBColor -------------------------------------------------------------- // --- tRGBColor --------------------------------------------------------------
typedef struct typedef struct
...@@ -139,8 +182,23 @@ typedef struct ...@@ -139,8 +182,23 @@ typedef struct
// --- tColorPacket ----------------------------------------------------------- // --- tColorPacket -----------------------------------------------------------
typedef struct typedef struct
{ {
tRGBColor channel[ATMO_NUM_CHANNELS]; int numColors;
} tColorPacket; 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 ------------------------------------------------------- // --- tRGBColorLongInt -------------------------------------------------------
typedef struct typedef struct
...@@ -151,14 +209,28 @@ typedef struct ...@@ -151,14 +209,28 @@ typedef struct
// --- tColorPacketLongInt ---------------------------------------------------- // --- tColorPacketLongInt ----------------------------------------------------
typedef struct typedef struct
{ {
tRGBColorLongInt channel[ATMO_NUM_CHANNELS]; int numColors;
} tColorPacketLongInt; 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 ---------------------------------------------------------- // --- tWeightPacket ----------------------------------------------------------
/*
typedef struct typedef struct
{ {
int channel[ATMO_NUM_CHANNELS]; int channel[CAP_MAX_NUM_ZONES];
} tWeightPacket; } tWeightPacket;
*/
// --- tHSVColor -------------------------------------------------------------- // --- tHSVColor --------------------------------------------------------------
typedef struct 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 ...@@ -17,8 +17,10 @@ CAtmoDynData::CAtmoDynData(vlc_object_t *p_atmo_filter, CAtmoConfig *pAtmoConfig
this->m_pAtmoConnection = NULL; this->m_pAtmoConnection = NULL;
this->m_pCurrentEffectThread = NULL; this->m_pCurrentEffectThread = NULL;
this->m_pLivePacketQueue = NULL;
this->m_pLiveInput = NULL;
this->m_LivePictureSource = lpsExtern;
vlc_mutex_init( &m_lock ); vlc_mutex_init( &m_lock );
} }
#else #else
CAtmoDynData::CAtmoDynData(HINSTANCE hInst, CAtmoConfig *pAtmoConfig, CAtmoDisplays *pAtmoDisplays) { CAtmoDynData::CAtmoDynData(HINSTANCE hInst, CAtmoConfig *pAtmoConfig, CAtmoDisplays *pAtmoDisplays) {
...@@ -27,7 +29,11 @@ CAtmoDynData::CAtmoDynData(HINSTANCE hInst, CAtmoConfig *pAtmoConfig, CAtmoDispl ...@@ -27,7 +29,11 @@ CAtmoDynData::CAtmoDynData(HINSTANCE hInst, CAtmoConfig *pAtmoConfig, CAtmoDispl
this->m_pAtmoConnection = NULL; this->m_pAtmoConnection = NULL;
this->m_pCurrentEffectThread = NULL; this->m_pCurrentEffectThread = NULL;
this->m_hInst = hInst; this->m_hInst = hInst;
InitializeCriticalSection(&m_RemoteCallCriticalSection);
this->m_pLivePacketQueue = NULL;
this->m_pLiveInput = NULL;
this->m_LivePictureSource = lpsScreenCapture;
InitializeCriticalSection( &m_RemoteCallCriticalSection );
} }
#endif #endif
...@@ -55,3 +61,187 @@ void CAtmoDynData::UnLockCriticalSection() { ...@@ -55,3 +61,187 @@ void CAtmoDynData::UnLockCriticalSection() {
LeaveCriticalSection(&m_RemoteCallCriticalSection); LeaveCriticalSection(&m_RemoteCallCriticalSection);
#endif #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 @@ ...@@ -9,11 +9,15 @@
#ifndef _AtmoDynData_h_ #ifndef _AtmoDynData_h_
#define _AtmoDynData_h_ #define _AtmoDynData_h_
#include <stdio.h>
#include "AtmoDefs.h" #include "AtmoDefs.h"
#include "AtmoThread.h" #include "AtmoThread.h"
#include "AtmoConfig.h" #include "AtmoConfig.h"
#include "AtmoConnection.h" #include "AtmoConnection.h"
#include "AtmoPacketQueue.h"
#include "AtmoInput.h"
#if !defined(_ATMO_VLC_PLUGIN_) #if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoDisplays.h" # include "AtmoDisplays.h"
...@@ -22,6 +26,8 @@ ...@@ -22,6 +26,8 @@
# include <vlc_threads.h> # include <vlc_threads.h>
#endif #endif
class CAtmoInput;
/* /*
the idea behind this class is to avoid a mix of persistent value and the idea behind this class is to avoid a mix of persistent value and
volatile values in CAtmoConfig class because some parameters and variables volatile values in CAtmoConfig class because some parameters and variables
...@@ -31,22 +37,45 @@ ...@@ -31,22 +37,45 @@
you ask? why I didn't used a struct for it? ..mmh I like classes? 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 Allways stop the current effect Thread before changing AtmoConnection or
AtmoConfig! AtmoConfig!
*/ */
class CAtmoDynData class CAtmoDynData
{ {
private: private:
/*
thread creating the current output (depends on active effect)
*/
CThread *m_pCurrentEffectThread; 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; CAtmoConnection *m_pAtmoConnection;
/*
all global persistent parameters
*/
CAtmoConfig *m_pAtmoConfig; CAtmoConfig *m_pAtmoConfig;
#if !defined(_ATMO_VLC_PLUGIN_) #if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays *m_pAtmoDisplays; CAtmoDisplays *m_pAtmoDisplays;
HINSTANCE m_hInst; HINSTANCE m_hInst;
CRITICAL_SECTION m_RemoteCallCriticalSection; CRITICAL_SECTION m_RemoteCallCriticalSection;
char m_WorkDir[MAX_PATH];
#else #else
vlc_object_t *p_atmo_filter; vlc_object_t *p_atmo_filter;
vlc_mutex_t m_lock; vlc_mutex_t m_lock;
...@@ -67,14 +96,29 @@ public: ...@@ -67,14 +96,29 @@ public:
CThread *getEffectThread() { return m_pCurrentEffectThread; } CThread *getEffectThread() { return m_pCurrentEffectThread; }
void setEffectThread(CThread *value) { m_pCurrentEffectThread = value; } 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; } CAtmoConnection *getAtmoConnection() { return m_pAtmoConnection; }
void setAtmoConnection(CAtmoConnection *value) { m_pAtmoConnection = value; } void setAtmoConnection(CAtmoConnection *value) { m_pAtmoConnection = value; }
CAtmoConfig *getAtmoConfig() { return m_pAtmoConfig; } CAtmoConfig *getAtmoConfig() { return m_pAtmoConfig; }
void ReloadZoneDefinitionBitmaps();
void CalculateDefaultZones();
#if !defined(_ATMO_VLC_PLUGIN_) #if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays *getAtmoDisplays() { return m_pAtmoDisplays; } CAtmoDisplays *getAtmoDisplays() { return m_pAtmoDisplays; }
HINSTANCE getHinstance() { return m_hInst; } HINSTANCE getHinstance() { return m_hInst; }
void setWorkDir(const char *dir);
char *getWorkDir();
#else #else
vlc_object_t *getAtmoFilter() { return p_atmo_filter; } vlc_object_t *getAtmoFilter() { return p_atmo_filter; }
#endif #endif
......
...@@ -11,21 +11,20 @@ ...@@ -11,21 +11,20 @@
#include "AtmoExternalCaptureInput.h" #include "AtmoExternalCaptureInput.h"
#include "AtmoTools.h" #include "AtmoTools.h"
#if defined(_ATMO_VLC_PLUGIN_)
#ifndef INT64_C #ifndef INT64_C
#define INT64_C(c) c ## LL #define INT64_C(c) c ## LL
#endif #endif
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) : CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) :
CAtmoInput(pAtmoDynData), CAtmoInput(pAtmoDynData)
CThread(pAtmoDynData->getAtmoFilter())
{ {
m_pCurrentFramePixels = NULL;
vlc_cond_init( &m_WakeupCond ); vlc_cond_init( &m_WakeupCond );
vlc_mutex_init( &m_WakeupLock ); vlc_mutex_init( &m_WakeupLock );
msg_Dbg( m_pAtmoThread, "CAtmoExternalCaptureInput created."); m_pCurrentFramePixels = NULL;
} }
#else #else
...@@ -33,7 +32,8 @@ CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) ...@@ -33,7 +32,8 @@ CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData)
CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) : CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) :
CAtmoInput(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; m_pCurrentFramePixels = NULL;
} }
...@@ -42,14 +42,19 @@ CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) ...@@ -42,14 +42,19 @@ CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData)
CAtmoExternalCaptureInput::~CAtmoExternalCaptureInput(void) CAtmoExternalCaptureInput::~CAtmoExternalCaptureInput(void)
{ {
/* if there is still an unprocessed bufferpicture do kill it */ /* if there is still an unprocessed bufferpicture do kill it */
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_WakeupLock );
free( m_pCurrentFramePixels ); free( m_pCurrentFramePixels );
vlc_mutex_unlock( &m_WakeupLock );
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_destroy( &m_WakeupCond ); vlc_cond_destroy( &m_WakeupCond );
vlc_mutex_destroy(&m_WakeupLock); vlc_mutex_destroy( &m_WakeupLock );
msg_Dbg( m_pAtmoThread, "CAtmoExternalCaptureInput destroyed.");
#else #else
EnterCriticalSection( &m_BufferLock );
free( m_pCurrentFramePixels );
LeaveCriticalSection( &m_BufferLock );
CloseHandle(m_hWakeupEvent); CloseHandle(m_hWakeupEvent);
DeleteCriticalSection( &m_BufferLock );
#endif #endif
} }
...@@ -67,10 +72,6 @@ ATMO_BOOL CAtmoExternalCaptureInput::Close(void) ...@@ -67,10 +72,6 @@ ATMO_BOOL CAtmoExternalCaptureInput::Close(void)
return ATMO_TRUE; 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 this method will be called from another thread or possible the COM Server to feed
...@@ -91,6 +92,12 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI ...@@ -91,6 +92,12 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI
so it's nearly impossible that two frames are delivert in the same time so it's nearly impossible that two frames are delivert in the same time
the test needs and malloc needs... 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 ) if( !m_pCurrentFramePixels )
{ {
// Last Frame was processed... take this one... // Last Frame was processed... take this one...
...@@ -106,12 +113,12 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI ...@@ -106,12 +113,12 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI
memcpy(m_pCurrentFramePixels,pixelData,PixelDataSize); memcpy(m_pCurrentFramePixels,pixelData,PixelDataSize);
} }
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
#error This makes no sense!
vlc_mutex_lock( &m_WakeupLock );
vlc_cond_signal( &m_WakeupCond ); vlc_cond_signal( &m_WakeupCond );
vlc_mutex_unlock( &m_WakeupLock ); vlc_mutex_unlock( &m_WakeupLock );
// msg_Dbg( m_pAtmoThread, "DeliverNewSourceDataPaket done.");
#else #else
SetEvent(m_hWakeupEvent); SetEvent(m_hWakeupEvent);
LeaveCriticalSection( &m_BufferLock );
#endif #endif
} }
...@@ -125,24 +132,17 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI ...@@ -125,24 +132,17 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI
DWORD CAtmoExternalCaptureInput::Execute(void) DWORD CAtmoExternalCaptureInput::Execute(void)
{ {
msg_Dbg( m_pAtmoThread, "CAtmoExternalCaptureInput::Execute(void)"); while ((this->m_bTerminated == ATMO_FALSE) && (this->m_pAtmoThread->b_die == false)) {
int i = 0;
vlc_mutex_lock( &m_WakeupLock ); 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! */ /* DeliverNewSourceDataPaket delivered new work for me... get it! */
if(m_pCurrentFramePixels)
CalcColors(); // read picture and calculate colors CalcColors(); // read picture and calculate colors
this->m_FrameArrived = ATMO_TRUE;
}
i++;
if(i == 100) {
i = 0;
}
}
vlc_mutex_unlock( &m_WakeupLock ); vlc_mutex_unlock( &m_WakeupLock );
}
msg_Dbg( m_pAtmoThread, "DWORD CAtmoExternalCaptureInput::Execute(void) bailed out?");
return 0; return 0;
} }
...@@ -155,14 +155,16 @@ DWORD CAtmoExternalCaptureInput::Execute(void) { ...@@ -155,14 +155,16 @@ DWORD CAtmoExternalCaptureInput::Execute(void) {
handles[1] = m_hWakeupEvent; handles[1] = m_hWakeupEvent;
while (this->m_bTerminated == ATMO_FALSE) { 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) { if(event == WAIT_OBJECT_0) {
// Terminate Thread Event was set... say good bye...! // Terminate Thread Event was set... say good bye...!
break; break;
} }
if(event == (WAIT_OBJECT_0+1)) { if(event == (WAIT_OBJECT_0+1)) {
EnterCriticalSection( &m_BufferLock );
if(m_pCurrentFramePixels)
CalcColors(); // read picture and calculate colors CalcColors(); // read picture and calculate colors
this->m_FrameArrived = ATMO_TRUE; LeaveCriticalSection( &m_BufferLock );
} }
} }
return 0; return 0;
...@@ -171,46 +173,16 @@ DWORD CAtmoExternalCaptureInput::Execute(void) { ...@@ -171,46 +173,16 @@ DWORD CAtmoExternalCaptureInput::Execute(void) {
#endif #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 ... // take data from m_CurrentFrameHeader and m_pCurrentFramePixels .. process for atmo ...
tHSVColor HSV_Img[IMAGE_SIZE]; tHSVColor HSV_Img[IMAGE_SIZE];
tRGBColor pixelColor; tRGBColor pixelColor;
int srcIndex,index = 0; int srcIndex,index = 0;
memset(&HSV_Img,0,sizeof(HSV_Img)); memset(&HSV_Img,0,sizeof(HSV_Img));
// Convert Data to HSV values.. bla bla.... // msg_Dbg( m_pAtmoThread, "CalcColors start...");
if(m_pCurrentFramePixels!=NULL)
{
if((m_CurrentFrameHeader.biWidth == CAP_WIDTH) && (m_CurrentFrameHeader.biHeight == CAP_HEIGHT)) if((m_CurrentFrameHeader.biWidth == CAP_WIDTH) && (m_CurrentFrameHeader.biHeight == CAP_HEIGHT))
{ {
...@@ -274,12 +246,17 @@ void CAtmoExternalCaptureInput::CalcColors() { ...@@ -274,12 +246,17 @@ void CAtmoExternalCaptureInput::CalcColors() {
} }
} }
} }
/* /*
else {
if the image color format wasn't recognized - the output if the image color format wasn't recognized - the output
will be black (memset) 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, now convert the pixeldata into one RGB trippel for each channel,
this is done by some very sophisticated methods and statistics ... this is done by some very sophisticated methods and statistics ...
...@@ -287,18 +264,11 @@ void CAtmoExternalCaptureInput::CalcColors() { ...@@ -287,18 +264,11 @@ void CAtmoExternalCaptureInput::CalcColors() {
the only thing I know - the pixel priority is controled by some the only thing I know - the pixel priority is controled by some
gradients for each edge of the picture 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...) are done by some one else...)
*/ */
m_ColorPacket = CalcColorsAnalyzeHSV(this->m_pAtmoDynData->getAtmoConfig(), HSV_Img); //msg_Dbg( m_pAtmoThread, "CalcColors ende AddPacket...");
m_pAtmoDynData->getLivePacketQueue()->AddPacket( m_pAtmoColorCalculator->AnalyzeHSV( HSV_Img ) );
/* remove the source buffe */ //msg_Dbg( m_pAtmoThread, "CalcColors ende AddPacket...done.");
free(m_pCurrentFramePixels);
/*
the buffer zereo so that deliver new data paket will wakeup the
thread on the next frame again
*/
m_pCurrentFramePixels = NULL;
}
} }
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
# endif # endif
#endif #endif
#if !defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
# include <comdef.h> # include <vlc_common.h>
# include "AtmoWin_h.h" # include <vlc_threads.h>
#endif #endif
#include "AtmoInput.h" #include "AtmoInput.h"
...@@ -24,9 +24,7 @@ ...@@ -24,9 +24,7 @@
#include "AtmoCalculations.h" #include "AtmoCalculations.h"
class CAtmoExternalCaptureInput : class CAtmoExternalCaptureInput : public CAtmoInput
public CAtmoInput,
public CThread
{ {
protected: protected:
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
...@@ -34,6 +32,7 @@ protected: ...@@ -34,6 +32,7 @@ protected:
vlc_mutex_t m_WakeupLock; vlc_mutex_t m_WakeupLock;
#else #else
HANDLE m_hWakeupEvent; HANDLE m_hWakeupEvent;
CRITICAL_SECTION m_BufferLock;
#endif #endif
BITMAPINFOHEADER m_CurrentFrameHeader; BITMAPINFOHEADER m_CurrentFrameHeader;
...@@ -67,17 +66,6 @@ public: ...@@ -67,17 +66,6 @@ public:
*/ */
virtual ATMO_BOOL Close(void); 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 #endif
...@@ -7,20 +7,25 @@ ...@@ -7,20 +7,25 @@
* *
* $Id$ * $Id$
*/ */
#include "AtmoDefs.h"
#include "AtmoInput.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());
} }
#else
CAtmoInput::~CAtmoInput(void) 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 @@ ...@@ -11,17 +11,21 @@
#define _AtmoInput_h_ #define _AtmoInput_h_
#include "AtmoDefs.h" #include "AtmoDefs.h"
#include "AtmoCalculations.h"
#include "AtmoPacketQueue.h"
#include "AtmoThread.h"
#include "AtmoDynData.h" #include "AtmoDynData.h"
class CAtmoDynData;
/* /*
basic definition of an AtmoLight data/image source ... basic definition of an AtmoLight data/image source ...
*/ */
class CAtmoInput { class CAtmoInput : public CThread {
protected: protected:
tColorPacket m_ColorPacket;
volatile ATMO_BOOL m_FrameArrived;
CAtmoDynData *m_pAtmoDynData; CAtmoDynData *m_pAtmoDynData;
CAtmoColorCalculator *m_pAtmoColorCalculator;
public: public:
CAtmoInput(CAtmoDynData *pAtmoDynData); CAtmoInput(CAtmoDynData *pAtmoDynData);
...@@ -35,11 +39,6 @@ public: ...@@ -35,11 +39,6 @@ public:
// Returns true if the input-device was closed successfully. // Returns true if the input-device was closed successfully.
virtual ATMO_BOOL Close(void) { return ATMO_FALSE; } 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 #endif
This diff is collapsed.
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
#include "AtmoDefs.h" #include "AtmoDefs.h"
#if !defined(_ATMO_VLC_PLUGIN_) #if !defined(_ATMO_VLC_PLUGIN_)
# include <comdef.h>
# include "AtmoWin_h.h"
# include <windows.h> # include <windows.h>
#endif #endif
...@@ -28,32 +26,12 @@ class CAtmoLiveView : public CThread ...@@ -28,32 +26,12 @@ class CAtmoLiveView : public CThread
protected: protected:
virtual DWORD Execute(void); virtual DWORD Execute(void);
#if !defined(_ATMO_VLC_PLUGIN_)
public:
STDMETHODIMP setLiveViewSource(enum ComLiveViewSource dwModus);
STDMETHODIMP getCurrentLiveViewSource(enum ComLiveViewSource *modus);
#endif
protected: protected:
CAtmoDynData *m_pAtmoDynData; 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: public:
CAtmoLiveView(CAtmoDynData *pAtmoDynData); CAtmoLiveView(CAtmoDynData *pAtmoDynData);
virtual ~CAtmoLiveView(void); virtual ~CAtmoLiveView(void);
CAtmoInput *getAtmoInput() { return m_pAtmoInput; }
#if !defined(_ATMO_VLC_PLUGIN_)
ComLiveViewSource getLiveViewSource() { return m_CurrentLiveViewSource; }
#endif
}; };
#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 @@ ...@@ -17,11 +17,16 @@
class CAtmoOutputFilter class CAtmoOutputFilter
{ {
private: private:
tColorPacket filter_input; // input of the filter //tColorPacket filter_input; // input of the filter wozu?
tColorPacket filter_output; // output of the filter //tColorPacket filter_output; // output of the filter
pColorPacket m_percent_filter_output_old;
void PercentFilter(ATMO_BOOL init); pColorPacket m_mean_filter_output_old;
void MeanFilter(ATMO_BOOL init); 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; CAtmoConfig *m_pAtmoConfig;
public: public:
...@@ -30,7 +35,7 @@ public: ...@@ -30,7 +35,7 @@ public:
CAtmoOutputFilter(CAtmoConfig *atmoConfig); CAtmoOutputFilter(CAtmoConfig *atmoConfig);
virtual ~CAtmoOutputFilter(void); virtual ~CAtmoOutputFilter(void);
void ResetFilter(void); void ResetFilter(void);
tColorPacket Filtering(tColorPacket ColorPacket); pColorPacket Filtering(pColorPacket ColorPacket);
}; };
#endif #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 @@ ...@@ -11,6 +11,7 @@
CThread::CThread(vlc_object_t *pOwner) CThread::CThread(vlc_object_t *pOwner)
{ {
m_bTerminated = ATMO_FALSE;
m_pAtmoThread = (atmo_thread_t *)vlc_object_create( pOwner, m_pAtmoThread = (atmo_thread_t *)vlc_object_create( pOwner,
sizeof(atmo_thread_t) ); sizeof(atmo_thread_t) );
if(m_pAtmoThread) if(m_pAtmoThread)
...@@ -29,9 +30,12 @@ CThread::CThread(vlc_object_t *pOwner) ...@@ -29,9 +30,12 @@ CThread::CThread(vlc_object_t *pOwner)
CThread::CThread(void) CThread::CThread(void)
{ {
m_bTerminated = ATMO_FALSE;
m_hThread = CreateThread(NULL, 0, CThread::ThreadProc , m_hThread = CreateThread(NULL, 0, CThread::ThreadProc ,
this, CREATE_SUSPENDED, &m_dwThreadID); this, CREATE_SUSPENDED, &m_dwThreadID);
m_hTerminateEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
m_hTerminateEvent = CreateEvent(NULL,0,0,NULL);
} }
#endif #endif
...@@ -81,9 +85,9 @@ void *CThread::ThreadProc(vlc_object_t *obj) ...@@ -81,9 +85,9 @@ void *CThread::ThreadProc(vlc_object_t *obj)
DWORD WINAPI CThread::ThreadProc(LPVOID lpParameter) DWORD WINAPI CThread::ThreadProc(LPVOID lpParameter)
{ {
CThread *aThread = (CThread *)lpParameter; CThread *pThread = (CThread *)lpParameter;
if(aThread) if(pThread)
return aThread->Execute(); return pThread->Execute();
else else
return (DWORD)-1; return (DWORD)-1;
} }
...@@ -107,19 +111,20 @@ void CThread::Terminate(void) ...@@ -107,19 +111,20 @@ void CThread::Terminate(void)
{ {
// Set Termination Flag and EventObject! // Set Termination Flag and EventObject!
// and wait for Termination // and wait for Termination
m_bTerminated = ATMO_TRUE;
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
if(m_pAtmoThread) if(m_pAtmoThread)
{ {
vlc_mutex_lock( &m_TerminateLock ); vlc_mutex_lock( &m_TerminateLock );
m_bTerminated = ATMO_TRUE;
vlc_cond_signal( &m_TerminateCond ); vlc_cond_signal( &m_TerminateCond );
vlc_mutex_unlock( &m_TerminateLock ); vlc_mutex_unlock( &m_TerminateLock );
vlc_object_kill( m_pAtmoThread );
vlc_object_kill( m_pAtmoThread );
vlc_thread_join( m_pAtmoThread ); vlc_thread_join( m_pAtmoThread );
} }
#else #else
m_bTerminated = ATMO_TRUE;
SetEvent(m_hTerminateEvent); SetEvent(m_hTerminateEvent);
WaitForSingleObject(m_hThread,INFINITE); WaitForSingleObject(m_hThread,INFINITE);
#endif #endif
...@@ -154,12 +159,14 @@ void CThread::Run() ...@@ -154,12 +159,14 @@ void CThread::Run()
ATMO_BOOL CThread::ThreadSleep(DWORD millisekunden) ATMO_BOOL CThread::ThreadSleep(DWORD millisekunden)
{ {
#if defined(_ATMO_VLC_PLUGIN_) #if defined(_ATMO_VLC_PLUGIN_)
ATMO_BOOL temp;
vlc_mutex_lock( &m_TerminateLock ); vlc_mutex_lock( &m_TerminateLock );
int value = vlc_cond_timedwait(&m_TerminateCond, vlc_cond_timedwait(&m_TerminateCond,
&m_TerminateLock, &m_TerminateLock,
mdate() + (mtime_t)(millisekunden * 1000)); mdate() + (mtime_t)(millisekunden * 1000));
temp = m_bTerminated;
vlc_mutex_unlock( &m_TerminateLock ); vlc_mutex_unlock( &m_TerminateLock );
return (value != 0); return !temp;
#else #else
DWORD res = WaitForSingleObject(m_hTerminateEvent,millisekunden); DWORD res = WaitForSingleObject(m_hTerminateEvent,millisekunden);
......
This diff is collapsed.
...@@ -26,11 +26,13 @@ private: ...@@ -26,11 +26,13 @@ private:
~CAtmoTools(void); ~CAtmoTools(void);
public: public:
static EffectMode SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode); static EffectMode SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode);
static LivePictureSource SwitchLiveSource(CAtmoDynData *pDynData, LivePictureSource newLiveSource);
static void ShowShutdownColor(CAtmoDynData *pDynData); static void ShowShutdownColor(CAtmoDynData *pDynData);
static ATMO_BOOL RecreateConnection(CAtmoDynData *pDynData); static ATMO_BOOL RecreateConnection(CAtmoDynData *pDynData);
static tColorPacket WhiteCalibration(CAtmoConfig *pAtmoConfig, tColorPacket ColorPacket); static pColorPacket WhiteCalibration(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket);
static tColorPacket ApplyGamma(CAtmoConfig *pAtmoConfig, tColorPacket ColorPacket); static pColorPacket ApplyGamma(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket);
static int SetChannelAssignment(CAtmoDynData *pDynData, int index); static int SetChannelAssignment(CAtmoDynData *pDynData, int index);
......
...@@ -25,12 +25,14 @@ void CAtmoZoneDefinition::Fill(unsigned char value) ...@@ -25,12 +25,14 @@ void CAtmoZoneDefinition::Fill(unsigned char value)
m_BasicWeight[i] = value; m_BasicWeight[i] = value;
} }
// max weight to left // 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; 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++) { for(int col=0; col < CAP_WIDTH; col++) {
// should be a value between 0 .. 255? // should be a value between 0 .. 255?
col_norm = (255 * (CAP_WIDTH-col-1)) / (CAP_WIDTH-1); col_norm = (255 * (CAP_WIDTH-col-1)) / (CAP_WIDTH-1);
...@@ -40,11 +42,12 @@ void CAtmoZoneDefinition::FillGradientFromLeft() ...@@ -40,11 +42,12 @@ void CAtmoZoneDefinition::FillGradientFromLeft()
} }
// max weight to right // 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; 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++) { for(int col=0; col < CAP_WIDTH; col++) {
col_norm = (255 * col) / (CAP_WIDTH-1); // should be a value between 0 .. 255? col_norm = (255 * col) / (CAP_WIDTH-1); // should be a value between 0 .. 255?
m_BasicWeight[index++] = col_norm; m_BasicWeight[index++] = col_norm;
...@@ -53,31 +56,131 @@ void CAtmoZoneDefinition::FillGradientFromRight() ...@@ -53,31 +56,131 @@ void CAtmoZoneDefinition::FillGradientFromRight()
} }
// max weight from top // 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; unsigned char row_norm;
for(int row=0; row < CAP_HEIGHT; row++) { 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? 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; m_BasicWeight[index++] = row_norm;
} }
} }
} }
// max weight from bottom // 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; unsigned char row_norm;
for(int row=0; row < CAP_HEIGHT; row++) { 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? 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; 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) int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
{ {
...@@ -88,6 +191,7 @@ int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap) ...@@ -88,6 +191,7 @@ int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
BITMAPFILEHEADER bmpFileHeader; BITMAPFILEHEADER bmpFileHeader;
/* /*
ATMO_LOAD_GRADIENT_FILENOTFOND
#define ATMO_LOAD_GRADIENT_OK 0 #define ATMO_LOAD_GRADIENT_OK 0
#define ATMO_LOAD_GRADIENT_FAILED_SIZE 1 #define ATMO_LOAD_GRADIENT_FAILED_SIZE 1
#define ATMO_LOAD_GRADIENT_FAILED_HEADER 2 #define ATMO_LOAD_GRADIENT_FAILED_HEADER 2
...@@ -103,11 +207,8 @@ int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap) ...@@ -103,11 +207,8 @@ int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
fclose(bmp); fclose(bmp);
return ATMO_LOAD_GRADIENT_FAILED_SIZE; return ATMO_LOAD_GRADIENT_FAILED_SIZE;
} }
#ifdef _ATMO_VLC_PLUGIN_
if(bmpFileHeader.bfType != VLC_TWOCC('M','B')) if(bmpFileHeader.bfType != MakeIntelWord('M','B'))
#else
if(bmpFileHeader.bfType != MakeWord('M','B'))
#endif
{ {
fclose(bmp); fclose(bmp);
return ATMO_LOAD_GRADIENT_FAILED_HEADER; return ATMO_LOAD_GRADIENT_FAILED_HEADER;
......
...@@ -21,12 +21,16 @@ public: ...@@ -21,12 +21,16 @@ public:
~CAtmoZoneDefinition(void); ~CAtmoZoneDefinition(void);
void Fill(unsigned char value); void Fill(unsigned char value);
void FillGradientFromLeft(); void FillGradientFromLeft(int start_row,int end_row);
void FillGradientFromRight(); void FillGradientFromRight(int start_row,int end_row);
void FillGradientFromTop(); void FillGradientFromTop(int start_col,int end_col);
void FillGradientFromBottom(); void FillGradientFromBottom(int start_col,int end_col);
int LoadGradientFromBitmap(char *pszBitmap); int LoadGradientFromBitmap(char *pszBitmap);
#if !defined(_ATMO_VLC_PLUGIN_)
void SaveZoneBitmap(char *);
void SaveWeightBitmap(char *fileName,int *weight);
#endif
void UpdateWeighting(int *destWeight, void UpdateWeighting(int *destWeight,
int WidescreenMode, 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