Commit 6713041e authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

atmo: remove video filter

parent 651687f3
...@@ -157,6 +157,9 @@ Misc ...@@ -157,6 +157,9 @@ Misc
* remove ZPL playlist format * remove ZPL playlist format
* Update libVLC doxygen modules * Update libVLC doxygen modules
Removed modules
* Atmo video filter
Changes between 2.2.0 and 2.2.1: Changes between 2.2.0 and 2.2.1:
-------------------------------- --------------------------------
......
...@@ -3902,18 +3902,6 @@ AS_IF([test "${enable_vsxu}" != "no"], ...@@ -3902,18 +3902,6 @@ AS_IF([test "${enable_vsxu}" != "no"],
]) ])
]) ])
dnl
dnl AtmoLight (homemade Philips Ambilight clone)
dnl
AC_ARG_ENABLE(atmo,
AS_HELP_STRING([--disable-atmo],[AtmoLight (homemade Philips Ambilight clone)
(default enabled)]),, [enable_atmo="yes"])
AS_IF([test "${enable_atmo}" != no], [
AS_IF([test "${SYS}" = "mingw32" -o "${SYS}" = "linux"], [
VLC_ADD_PLUGIN([atmo])
])
])
EXTEND_HELP_STRING([Service Discovery plugins:]) EXTEND_HELP_STRING([Service Discovery plugins:])
dnl dnl
dnl Bonjour services discovery dnl Bonjour services discovery
......
...@@ -42,7 +42,6 @@ $Id$ ...@@ -42,7 +42,6 @@ $Id$
* aribcam: ARIB STD-B25 decoder/virtual CAM * aribcam: ARIB STD-B25 decoder/virtual CAM
* aribsub: ARIB subtitles decoder * aribsub: ARIB subtitles decoder
* asf: ASF demuxer * asf: ASF demuxer
* atmo: Ambilight-like video-output
* attachment: Attachment access module * attachment: Attachment access module
* au: AU file demuxer * au: AU file demuxer
* audio_format: helper module for audio transcoding * audio_format: helper module for audio transcoding
......
...@@ -106,31 +106,6 @@ video_filter_LTLIBRARIES = \ ...@@ -106,31 +106,6 @@ video_filter_LTLIBRARIES = \
libpuzzle_plugin.la \ libpuzzle_plugin.la \
librotate_plugin.la librotate_plugin.la
libatmo_plugin_la_SOURCES = video_filter/atmo/atmo.cpp \
video_filter/atmo/AtmoDefs.h \
video_filter/atmo/AtmoCalculations.cpp video_filter/atmo/AtmoCalculations.h \
video_filter/atmo/AtmoConfig.cpp video_filter/atmo/AtmoConfig.h \
video_filter/atmo/AtmoConnection.cpp video_filter/atmo/AtmoConnection.h \
video_filter/atmo/AtmoDynData.cpp video_filter/atmo/AtmoDynData.h \
video_filter/atmo/AtmoExternalCaptureInput.cpp video_filter/atmo/AtmoExternalCaptureInput.h \
video_filter/atmo/AtmoInput.cpp video_filter/atmo/AtmoInput.h \
video_filter/atmo/AtmoLiveView.cpp video_filter/atmo/AtmoLiveView.h \
video_filter/atmo/AtmoOutputFilter.cpp video_filter/atmo/AtmoOutputFilter.h \
video_filter/atmo/AtmoThread.cpp video_filter/atmo/AtmoThread.h \
video_filter/atmo/AtmoTools.cpp video_filter/atmo/AtmoTools.h \
video_filter/atmo/AtmoZoneDefinition.cpp video_filter/atmo/AtmoZoneDefinition.h \
video_filter/atmo/AtmoChannelAssignment.cpp video_filter/atmo/AtmoChannelAssignment.h \
video_filter/atmo/AtmoClassicConnection.cpp video_filter/atmo/AtmoClassicConnection.h \
video_filter/atmo/AtmoDmxSerialConnection.cpp video_filter/atmo/AtmoDmxSerialConnection.h \
video_filter/atmo/DmxTools.cpp video_filter/atmo/DmxTools.h \
video_filter/atmo/AtmoMultiConnection.cpp video_filter/atmo/AtmoMultiConnection.h \
video_filter/atmo/MoMoConnection.cpp video_filter/atmo/MoMoConnection.h \
video_filter/atmo/FnordlichtConnection.cpp video_filter/atmo/FnordlichtConnection.h \
video_filter/atmo/AtmoPacketQueue.cpp video_filter/atmo/AtmoPacketQueue.h
libatmo_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(video_filterdir)'
video_filter_LTLIBRARIES += $(LTLIBatmo)
EXTRA_LTLIBRARIES += libatmo_plugin.la
libdeinterlace_plugin_la_SOURCES = \ libdeinterlace_plugin_la_SOURCES = \
video_filter/deinterlace/deinterlace.c video_filter/deinterlace/deinterlace.h \ video_filter/deinterlace/deinterlace.c video_filter/deinterlace/deinterlace.h \
video_filter/deinterlace/mmx.h video_filter/deinterlace/common.h \ video_filter/deinterlace/mmx.h video_filter/deinterlace/common.h \
......
This diff is collapsed.
/*
* AtmoCalculations.h: see calculations.h of the linux version... one to one copy
* calculations.h: calculations needed by the input devices
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoCalculations_h_
#define _AtmoCalculations_h_
#include "AtmoDefs.h"
#include "AtmoConfig.h"
#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();
};
tHSVColor RGB2HSV(tRGBColor color);
tRGBColor HSV2RGB(tHSVColor color);
#endif
/*
* 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$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#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)
{
delete[] m_mappings;
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_num_channels = numChannels;
if(m_num_channels > 0)
{
m_mappings = new int[m_num_channels];
memset(m_mappings, 0, sizeof(int) * m_num_channels);
}
else
m_mappings = NULL;
}
}
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
/*
* AtmoClassicConnection.cpp: Class for communication with the serial hardware of
* Atmo Light, opens and configures the serial port
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "AtmoDefs.h"
#include "AtmoClassicConnection.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoClassicConfigDialog.h"
#endif
#include <stdio.h>
#include <fcntl.h>
#if !defined(_WIN32)
#include <termios.h>
#include <unistd.h>
#include <vlc_fs.h>
#endif
CAtmoClassicConnection::CAtmoClassicConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg) {
m_hComport = INVALID_HANDLE_VALUE;
}
CAtmoClassicConnection::~CAtmoClassicConnection() {
}
ATMO_BOOL CAtmoClassicConnection::OpenConnection() {
#if defined(_ATMO_VLC_PLUGIN_)
char *serdevice = m_pAtmoConfig->getSerialDevice();
if(!serdevice)
return ATMO_FALSE;
#else
int portNummer = m_pAtmoConfig->getComport();
m_dwLastWin32Error = 0;
if(portNummer < 1) return ATMO_FALSE; // make no real sense;-)
#endif
CloseConnection();
#if !defined(_ATMO_VLC_PLUGIN_)
char serdevice[16]; // com4294967295
sprintf(serdevice,"com%d",portNummer);
#endif
#if defined(_WIN32)
m_hComport = CreateFileA(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; // für comport-parameter
dcb.DCBlength = sizeof(DCB);
GetCommState (m_hComport, &dcb); // ger current serialport settings
dcb.BaudRate = 38400; // set speed
dcb.ByteSize = 8; // set databits
dcb.Parity = NOPARITY; // set parity
dcb.StopBits = ONESTOPBIT; // set one stop bit
SetCommState (m_hComport, &dcb); // apply settings
#else
int bconst = B38400;
m_hComport = vlc_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 CAtmoClassicConnection::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 CAtmoClassicConnection::isOpen(void) {
return (m_hComport != INVALID_HANDLE_VALUE);
}
ATMO_BOOL CAtmoClassicConnection::HardwareWhiteAdjust(int global_gamma,
int global_contrast,
int contrast_red,
int contrast_green,
int contrast_blue,
int gamma_red,
int gamma_green,
int gamma_blue,
ATMO_BOOL storeToEeprom) {
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
DWORD iBytesWritten;
/*
[0] = 255
[1] = 00
[2] = 00
[3] = 101
[4] brightness 0..255 ?
[5] Contrast Red 11 .. 100
[6] Contrast Green 11 .. 100
[7] Contrast Blue 11 .. 100
[8] Gamma Red 11 .. 35
[9] Gamma Red 11 .. 35
[10] Gamma Red 11 .. 35
[11] Globale Contrast 11 .. 100
[12] Store Data: 199 (else 0)
*/
unsigned char sendBuffer[16];
sendBuffer[0] = 0xFF;
sendBuffer[1] = 0x00;
sendBuffer[2] = 0x00;
sendBuffer[3] = 101;
sendBuffer[4] = (global_gamma & 255);
sendBuffer[5] = (contrast_red & 255);
sendBuffer[6] = (contrast_green & 255);
sendBuffer[7] = (contrast_blue & 255);
sendBuffer[8] = (gamma_red & 255);
sendBuffer[9] = (gamma_green & 255);
sendBuffer[10] = (gamma_blue & 255);
sendBuffer[11] = (global_contrast & 255);
if(storeToEeprom == ATMO_TRUE)
sendBuffer[12] = 199; // store to eeprom!
else
sendBuffer[12] = 0;
#if defined(_WIN32)
WriteFile(m_hComport, sendBuffer, 13, &iBytesWritten, NULL); // send to COM-Port
#else
iBytesWritten = write(m_hComport, sendBuffer, 13);
tcdrain(m_hComport);
#endif
return (iBytesWritten == 13) ? ATMO_TRUE : ATMO_FALSE;
}
ATMO_BOOL CAtmoClassicConnection::SendData(pColorPacket data) {
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
unsigned char buffer[19];
DWORD iBytesWritten;
buffer[0] = 0xFF; // Start Byte
buffer[1] = 0x00; // Start channel 0
buffer[2] = 0x00; // Start channel 0
buffer[3] = 15; //
int iBuffer = 4;
int idx;
Lock();
for(int i=0; i < 5 ; i++) {
if(m_ChannelAssignment && (i < m_NumAssignedChannels))
idx = m_ChannelAssignment[i];
else
idx = -1;
if((idx>=0) && (idx<data->numColors)) {
buffer[iBuffer++] = data->zone[idx].r;
buffer[iBuffer++] = data->zone[idx].g;
buffer[iBuffer++] = data->zone[idx].b;
} else {
buffer[iBuffer++] = 0;
buffer[iBuffer++] = 0;
buffer[iBuffer++] = 0;
}
}
#if defined(_WIN32)
WriteFile(m_hComport, buffer, 19, &iBytesWritten, NULL); // send to COM-Port
#else
iBytesWritten = write(m_hComport, buffer, 19);
tcdrain(m_hComport);
#endif
Unlock();
return (iBytesWritten == 19) ? ATMO_TRUE : ATMO_FALSE;
}
ATMO_BOOL CAtmoClassicConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
{
if(!ca) return ATMO_FALSE;
ca->setSize(5);
ca->setZoneIndex(0, 4); // Zone 5
ca->setZoneIndex(1, 3);
ca->setZoneIndex(2, 1);
ca->setZoneIndex(3, 0);
ca->setZoneIndex(4, 2);
return ATMO_TRUE;
}
#if !defined(_ATMO_VLC_PLUGIN_)
char *CAtmoClassicConnection::getChannelName(int ch)
{
if(ch < 0) return NULL;
char buf[30];
switch(ch) {
case 0:
sprintf(buf,"Summen Kanal [%d]",ch);
break;
case 1:
sprintf(buf,"Linker Kanal [%d]",ch);
break;
case 2:
sprintf(buf,"Rechter Kanal [%d]",ch);
break;
case 3:
sprintf(buf,"Oberer Kanal [%d]",ch);
break;
case 4:
sprintf(buf,"Unterer Kanal [%d]",ch);
break;
default:
sprintf(buf,"Kanal [%d]",ch);
break;
}
return strdup(buf);
}
ATMO_BOOL CAtmoClassicConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
{
CAtmoClassicConfigDialog *dlg = new CAtmoClassicConfigDialog(hInst, parent, cfg);
INT_PTR result = dlg->ShowModal();
delete dlg;
if(result == IDOK)
return ATMO_TRUE;
else
return ATMO_FALSE;
}
#endif
/*
* AtmoClassicConnection.h: Class for communication with the serial hardware of Atmo Light,
* opens and configures the serial port
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoClassicConnection_h_
#define _AtmoClassicConnection_h_
#include "AtmoDefs.h"
#include "AtmoConnection.h"
#include "AtmoConfig.h"
#if defined(_WIN32)
# include <windows.h>
#endif
class CAtmoClassicConnection : public CAtmoConnection {
private:
HANDLE m_hComport;
#if defined(_WIN32)
DWORD m_dwLastWin32Error;
public:
DWORD getLastError() { return m_dwLastWin32Error; }
#endif
public:
CAtmoClassicConnection(CAtmoConfig *cfg);
virtual ~CAtmoClassicConnection(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 int getNumChannels() { return 5; }
virtual const char *getDevicePath() { return "atmo"; }
#if !defined(_ATMO_VLC_PLUGIN_)
virtual char *getChannelName(int ch);
virtual ATMO_BOOL ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg);
#endif
virtual ATMO_BOOL CreateDefaultMapping(CAtmoChannelAssignment *ca);
};
#endif
This diff is collapsed.
This diff is collapsed.
/*
* AtmoConnection.cpp: generic/abstract class defining all methods for the
* communication with the hardware
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include "AtmoConnection.h"
CAtmoConnection::CAtmoConnection(CAtmoConfig *cfg)
{
this->m_pAtmoConfig = cfg;
m_ChannelAssignment = NULL;
m_NumAssignedChannels = 0;
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_init( &m_AccessConnection );
#else
InitializeCriticalSection( &m_AccessConnection );
#endif
}
CAtmoConnection::~CAtmoConnection(void)
{
if(isOpen())
CloseConnection();
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_destroy( &m_AccessConnection );
#else
DeleteCriticalSection( &m_AccessConnection );
#endif
}
void CAtmoConnection::SetChannelAssignment(CAtmoChannelAssignment *ca)
{
if(ca)
{
Lock();
delete m_ChannelAssignment;
m_ChannelAssignment = ca->getMapArrayClone(m_NumAssignedChannels);
Unlock();
}
}
#if !defined(_ATMO_VLC_PLUGIN_)
ATMO_BOOL CAtmoConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
{
MessageBox(parent, "This device doesn't have a special config dialog", "Info", 0);
return ATMO_FALSE;
}
#endif
void CAtmoConnection::Lock()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_AccessConnection );
#else
EnterCriticalSection( &m_AccessConnection );
#endif
}
void CAtmoConnection::Unlock()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_unlock( &m_AccessConnection );
#else
LeaveCriticalSection( &m_AccessConnection );
#endif
}
/*
* AtmoConnection.h: generic/abstract class defining all methods for the
* communication with the hardware
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoConnection_h_
#define _AtmoConnection_h_
#include <stdlib.h>
#include "AtmoDefs.h"
#include "AtmoConfig.h"
#include "AtmoChannelAssignment.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc_common.h>
# include <vlc_threads.h>
#else
# include <windows.h>
#endif
class CAtmoConnection
{
protected:
CAtmoConfig *m_pAtmoConfig;
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_t m_AccessConnection;
#else
CRITICAL_SECTION m_AccessConnection;
#endif
int *m_ChannelAssignment;
int m_NumAssignedChannels;
protected:
void Lock();
void Unlock();
public:
CAtmoConnection(CAtmoConfig *cfg);
virtual ~CAtmoConnection(void);
virtual ATMO_BOOL OpenConnection() = 0;
virtual void CloseConnection() {};
virtual ATMO_BOOL isOpen(void) { return false; }
virtual ATMO_BOOL SendData(pColorPacket data) = 0;
virtual ATMO_BOOL setChannelColor(int /*channel*/, tRGBColor /*color*/)
{ return false; }
virtual ATMO_BOOL setChannelValues(int /*num*/,unsigned char * /*values*/)
{ return false; }
virtual ATMO_BOOL HardwareWhiteAdjust(int /*global_gamma*/,
int /*global_contrast*/,
int /*contrast_red*/,
int /*contrast_green*/,
int /*contrast_blue*/,
int /*gamma_red*/,
int /*gamma_green*/,
int /*gamma_blue*/,
ATMO_BOOL /*storeToEeprom*/)
{ return false; }
#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; }
};
#endif
/*
* AtmoDefs.h: a lot of globals defines for the color computation - most of this file
* is an one to one copy of "defs.h" from Atmo VDR Plugin
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoDefs_h_
#define _AtmoDefs_h_
#if defined(__LIBVLC__)
# include <vlc_common.h>
# include <vlc_codecs.h>
/* some things need to be changed if this code is used inside VideoLan Filter Module */
# define _ATMO_VLC_PLUGIN_
# define get_time mdate()
# define do_sleep(a) msleep(a)
#else
# define MakeDword(ch1,ch2,ch3,ch4) ((((DWORD)(ch1)&255) << 24) | \
(((DWORD)(ch2)&255) << 16) | \
(((DWORD)(ch3)&255) << 8) | \
(((DWORD)(ch4)&255)))
# define get_time GetTickCount()
# define do_sleep(a) Sleep(a)
#endif
#define ATMO_BOOL bool
#define ATMO_TRUE true
#define ATMO_FALSE false
/*
can't use the VLC_TWOCC macro because the byte order there is CPU dependent
but for the use in Atmo I need for this single purpose Intel Byte Order
every time!
*/
#define MakeIntelWord(ch1,ch2) ((((int)(ch1)&255)<<8) | \
((int)(ch2)&255))
// my own min max macros
#define ATMO_MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define ATMO_MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#if !defined(_WIN32)
#define INVALID_HANDLE_VALUE -1
typedef int HANDLE;
typedef unsigned long DWORD;
#define BI_RGB 0L
#if !defined(_BITMAPFILEHEADER_)
#define _BITMAPFILEHEADER_
typedef struct
#ifdef HAVE_ATTRIBUTE_PACKED
__attribute__((__packed__))
#endif
{
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
} BITMAPFILEHEADER, *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
#endif
#endif
// maximal Anzahl Kanäle... 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
# define CAP_WIDTH 88
# define CAP_HEIGHT 48
#else
# define CAP_WIDTH 64
# define CAP_HEIGHT 48
#endif
// imagesize
#define IMAGE_SIZE (CAP_WIDTH * CAP_HEIGHT)
/*
number of pixel the atmo zones should overlap - based on CAP_WIDTH and CAP_HEIGHT
*/
#define CAP_ZONE_OVERLAP 2
enum AtmoConnectionType
{
actClassicAtmo = 0,
actDummy = 1,
actDMX = 2,
actNUL = 3,
actMultiAtmo = 4,
actMondolight = 5,
actMoMoLight = 6,
actFnordlicht = 7
};
static const char AtmoDeviceTypes[8][16] = {
"Atmo-Classic",
"Dummy",
"DMX",
"Nul-Device",
"Multi-Atmo",
"Mondolight",
"MoMoLight",
"Fnordlicht"
};
#define ATMO_DEVICE_COUNT 8
#if defined(_ATMO_VLC_PLUGIN_)
enum EffectMode {
emUndefined = -1,
emDisabled = 0,
emStaticColor = 1,
emLivePicture = 2
};
enum LivePictureSource {
lpsDisabled = 0,
lpsExtern = 2
};
#else
enum EffectMode {
emUndefined = -1,
emDisabled = 0,
emStaticColor = 1,
emLivePicture = 2,
emColorChange = 3,
emLrColorChange = 4
};
enum LivePictureSource {
lpsDisabled = 0,
lpsScreenCapture = 1,
lpsExtern = 2
};
#endif
enum AtmoGammaCorrect {
agcNone = 0,
agcPerColor = 1,
agcGlobal = 2
};
enum AtmoFilterMode {
afmNoFilter,
afmCombined,
afmPercent
};
// --- tRGBColor --------------------------------------------------------------
typedef struct
{
unsigned char r, g, b;
} tRGBColor;
// --- tColorPacket -----------------------------------------------------------
typedef struct
{
int numColors;
tRGBColor zone[1];
} xColorPacket;
typedef xColorPacket* pColorPacket;
#define AllocColorPacket(packet, numColors_) packet = (pColorPacket)new char[sizeof(xColorPacket) + (numColors_)*sizeof(tRGBColor)]; \
packet->numColors = numColors_;
#define DupColorPacket(dest, source) dest = NULL; \
if(source) { \
dest = (pColorPacket)new char[sizeof(xColorPacket) + (source->numColors)*sizeof(tRGBColor)]; \
memcpy(dest, source, sizeof(xColorPacket) + (source->numColors)*sizeof(tRGBColor)); \
}
#define CopyColorPacket( source, dest) memcpy(dest, source, sizeof(xColorPacket) + (source->numColors)*sizeof(tRGBColor) );
#define ZeroColorPacket( packet ) memset( &((packet)->zone[0]), 0, (packet->numColors)*sizeof(tRGBColor));
// --- tRGBColorLongInt -------------------------------------------------------
typedef struct
{
long int r, g, b;
} tRGBColorLongInt;
// --- tColorPacketLongInt ----------------------------------------------------
typedef struct
{
int numColors;
tRGBColorLongInt longZone[1];
} xColorPacketLongInt;
typedef xColorPacketLongInt* pColorPacketLongInt;
#define AllocLongColorPacket(packet, numColors_) packet = (pColorPacketLongInt)new char[sizeof(xColorPacketLongInt) + (numColors_)*sizeof(tRGBColorLongInt)]; \
packet->numColors = numColors_;
#define DupLongColorPacket(dest, source) dest = NULL; \
if(source) { \
dest = (pColorPacketLongInt)new char[sizeof(xColorPacketLongInt) + (source->numColors)*sizeof(tRGBColorLongInt)]; \
memcpy(dest, source, sizeof(xColorPacketLongInt) + (source->numColors)*sizeof(tRGBColorLongInt)); \
}
#define ZeroLongColorPacket( packet ) memset( &((packet)->longZone[0]), 0, (packet->numColors)*sizeof(tRGBColorLongInt));
// --- tWeightPacket ----------------------------------------------------------
/*
typedef struct
{
int channel[CAP_MAX_NUM_ZONES];
} tWeightPacket;
*/
// --- tHSVColor --------------------------------------------------------------
typedef struct
{
unsigned char h, s, v;
} tHSVColor;
#endif
/*
* 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$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#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 = CreateFileA(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; // für 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::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 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
/*
* AtmoDynData.cpp: class for holding all variable data - which may be
* passed between function calls, into threads instead of the use
* of global variables
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "AtmoDynData.h"
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoDynData::CAtmoDynData(vlc_object_t *p_atmo_filter, CAtmoConfig *pAtmoConfig) {
this->p_atmo_filter = p_atmo_filter;
this->m_pAtmoConfig = pAtmoConfig;
this->m_pAtmoConnection = NULL;
this->m_pCurrentEffectThread = NULL;
this->m_pLivePacketQueue = NULL;
this->m_pLiveInput = NULL;
this->m_LivePictureSource = lpsExtern;
vlc_mutex_init( &m_lock );
}
#else
CAtmoDynData::CAtmoDynData(HINSTANCE hInst, CAtmoConfig *pAtmoConfig, CAtmoDisplays *pAtmoDisplays) {
this->m_pAtmoConfig = pAtmoConfig;
this->m_pAtmoDisplays = pAtmoDisplays;
this->m_pAtmoConnection = NULL;
this->m_pCurrentEffectThread = NULL;
this->m_hInst = hInst;
this->m_pLivePacketQueue = NULL;
this->m_pLiveInput = NULL;
this->m_LivePictureSource = lpsScreenCapture;
InitializeCriticalSection( &m_RemoteCallCriticalSection );
}
#endif
CAtmoDynData::~CAtmoDynData(void)
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_destroy( &m_lock );
#else
DeleteCriticalSection(&m_RemoteCallCriticalSection);
#endif
}
void CAtmoDynData::LockCriticalSection() {
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_lock );
#else
EnterCriticalSection(&m_RemoteCallCriticalSection);
#endif
}
void CAtmoDynData::UnLockCriticalSection() {
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_unlock( &m_lock );
#else
LeaveCriticalSection(&m_RemoteCallCriticalSection);
#endif
}
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 für 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
/*
* AtmoDynData.h: class for holding all variable data - which may be passed
* between function calls, into threads instead of the use of global variables
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoDynData_h_
#define _AtmoDynData_h_
#include <stdio.h>
#include "AtmoDefs.h"
#include "AtmoThread.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#include "AtmoPacketQueue.h"
#include "AtmoInput.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoDisplays.h"
#else
# include <vlc_common.h>
# include <vlc_threads.h>
#endif
class CAtmoInput;
/*
the idea behind this class is to avoid a mix of persistent value and
volatile values in CAtmoConfig class because some parameters and variables
exists only for the current process and won't be stored to the registry
(Simple thought its a container... )
you ask? why I didn't used a struct for it? ..mmh I like classes?
Always stop the current effect Thread before changing AtmoConnection or
AtmoConfig!
*/
class CAtmoDynData
{
private:
/*
thread creating the current output (depends on active effect)
*/
CThread *m_pCurrentEffectThread;
/*
in Modus Live View the packetQueue is the connection
between the output processing and the pixelsource
*/
CAtmoPacketQueue *m_pLivePacketQueue;
/*
thread for getting and preparing the pixeldata in color
packets for each zone
*/
CAtmoInput *m_pLiveInput;
LivePictureSource m_LivePictureSource;
/*
connection to the current configure hardware device
*/
CAtmoConnection *m_pAtmoConnection;
/*
all global persistent parameters
*/
CAtmoConfig *m_pAtmoConfig;
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays *m_pAtmoDisplays;
HINSTANCE m_hInst;
CRITICAL_SECTION m_RemoteCallCriticalSection;
char m_WorkDir[MAX_PATH];
#else
vlc_object_t *p_atmo_filter;
vlc_mutex_t m_lock;
#endif
public:
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDynData(HINSTANCE hInst,
CAtmoConfig *pAtmoConfig,
CAtmoDisplays *pAtmoDisplays);
#else
CAtmoDynData(vlc_object_t *p_atmo_filter,
CAtmoConfig *pAtmoConfig);
#endif
~CAtmoDynData(void);
CThread *getEffectThread() { return m_pCurrentEffectThread; }
void setEffectThread(CThread *value) { m_pCurrentEffectThread = value; }
CAtmoPacketQueue *getLivePacketQueue() { return m_pLivePacketQueue; }
void setLivePacketQueue(CAtmoPacketQueue *pQueue) { m_pLivePacketQueue = pQueue; }
CAtmoInput *getLiveInput() { return m_pLiveInput; }
void setLiveInput(CAtmoInput *value) { m_pLiveInput = value; }
LivePictureSource getLivePictureSource() { return m_LivePictureSource; }
void setLivePictureSource(LivePictureSource lps) { m_LivePictureSource = lps; }
CAtmoConnection *getAtmoConnection() { return m_pAtmoConnection; }
void setAtmoConnection(CAtmoConnection *value) { m_pAtmoConnection = value; }
CAtmoConfig *getAtmoConfig() { return m_pAtmoConfig; }
void ReloadZoneDefinitionBitmaps();
void CalculateDefaultZones();
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays *getAtmoDisplays() { return m_pAtmoDisplays; }
HINSTANCE getHinstance() { return m_hInst; }
void setWorkDir(const char *dir);
char *getWorkDir();
#else
vlc_object_t *getAtmoFilter() { return p_atmo_filter; }
#endif
void LockCriticalSection();
void UnLockCriticalSection();
};
#endif
/*
* AtmoExternalCaptureInput.cpp: Datasource which gets its data via a COM object call
* or some other external method.
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "AtmoExternalCaptureInput.h"
#include "AtmoTools.h"
#if defined(_ATMO_VLC_PLUGIN_)
#ifndef INT64_C
#define INT64_C(c) c ## LL
#endif
CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) :
CAtmoInput(pAtmoDynData)
{
vlc_cond_init( &m_WakeupCond );
vlc_mutex_init( &m_WakeupLock );
m_pCurrentFramePixels = NULL;
m_pLog = pAtmoDynData->getAtmoFilter();
}
#else
CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) :
CAtmoInput(pAtmoDynData)
{
m_hWakeupEvent = CreateEvent(NULL,0,0,NULL);
InitializeCriticalSection( &m_BufferLock );
m_pCurrentFramePixels = NULL;
}
#endif
CAtmoExternalCaptureInput::~CAtmoExternalCaptureInput(void)
{
/* if there is still an unprocessed bufferpicture do kill it */
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_WakeupLock );
free( m_pCurrentFramePixels );
vlc_mutex_unlock( &m_WakeupLock );
vlc_cond_destroy( &m_WakeupCond );
vlc_mutex_destroy( &m_WakeupLock );
#else
EnterCriticalSection( &m_BufferLock );
free( m_pCurrentFramePixels );
LeaveCriticalSection( &m_BufferLock );
CloseHandle(m_hWakeupEvent);
DeleteCriticalSection( &m_BufferLock );
#endif
}
ATMO_BOOL CAtmoExternalCaptureInput::Open()
{
this->Run();
return ATMO_TRUE;
}
// Closes the input-device.
// Returns true if the input-device was closed successfully.
ATMO_BOOL CAtmoExternalCaptureInput::Close(void)
{
this->Terminate();
return ATMO_TRUE;
}
/*
this method will be called from another thread or possible the COM Server to feed
new pixeldata into the calculation process it doest just the following:
1: check if last buffer was allready processed (!m_pCurrentFramePixels)
2. copy the bitmap info structure into the threads own one
3. alloc memory for frame
4. copy sourcepixeldata into own buffer...
5. let the thread wake up and return imediately to the caller
so that the real videoout wouldn't be stop for a too long time
*/
void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(VLC_BITMAPINFOHEADER *bmpInfoHeader,void *pixelData)
{
/*
normaly we should protect this area of code by critical_section or a mutex,
but I think we can omit this here because the timing this method is called
is really slow (in terms of the speed of a modern computer?)
so it's nearly impossible that two frames are delivert in the same time
the test needs and malloc needs...
*/
#if defined(_ATMO_VLC_PLUGIN_)
// msg_Dbg( m_pLog, "DeliverNewSourceDataPaket start...");
vlc_mutex_lock( &m_WakeupLock );
#else
EnterCriticalSection( &m_BufferLock );
#endif
if( !m_pCurrentFramePixels )
{
// Last Frame was processed... take this one...
memcpy(&m_CurrentFrameHeader,bmpInfoHeader,bmpInfoHeader->biSize);
int PixelDataSize = m_CurrentFrameHeader.biHeight * m_CurrentFrameHeader.biWidth;
switch(m_CurrentFrameHeader.biBitCount) {
case 8: /* PixelDataSize = PixelDataSize; */ break;
case 16: PixelDataSize = PixelDataSize * 2; break;
case 24: PixelDataSize = PixelDataSize * 3; break;
case 32: PixelDataSize = PixelDataSize * 4; break;
}
m_pCurrentFramePixels = malloc(PixelDataSize);
memcpy(m_pCurrentFramePixels,pixelData,PixelDataSize);
}
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_signal( &m_WakeupCond );
vlc_mutex_unlock( &m_WakeupLock );
// msg_Dbg( m_pLog, "DeliverNewSourceDataPaket done.");
#else
SetEvent(m_hWakeupEvent);
LeaveCriticalSection( &m_BufferLock );
#endif
}
/*
the real thread Method which is processing the pixeldata into the hardware channel
values - which are used by the thread AtmoLiveView...
*/
#if defined (_ATMO_VLC_PLUGIN_)
DWORD CAtmoExternalCaptureInput::Execute(void)
{
while (this->m_bTerminated == ATMO_FALSE) {
vlc_mutex_lock( &m_WakeupLock );
vlc_cond_timedwait(&m_WakeupCond, &m_WakeupLock, mdate() + 75000 );
/* DeliverNewSourceDataPaket delivered new work for me... get it! */
if(m_pCurrentFramePixels)
CalcColors(); // read picture and calculate colors
vlc_mutex_unlock( &m_WakeupLock );
}
msg_Dbg( m_pLog, "DWORD CAtmoExternalCaptureInput::Execute(void) bailed out?");
return 0;
}
#else
DWORD CAtmoExternalCaptureInput::Execute(void) {
HANDLE handles[2];
handles[0] = this->m_hTerminateEvent;
handles[1] = m_hWakeupEvent;
while (this->m_bTerminated == ATMO_FALSE) {
DWORD event = WaitForMultipleObjects(2, &handles[0], FALSE, INFINITE);
if(event == WAIT_OBJECT_0) {
// Terminate Thread Event was set... say good bye...!
break;
}
if(event == (WAIT_OBJECT_0+1)) {
EnterCriticalSection( &m_BufferLock );
if(m_pCurrentFramePixels)
CalcColors(); // read picture and calculate colors
LeaveCriticalSection( &m_BufferLock );
}
}
return 0;
}
#endif
void CAtmoExternalCaptureInput::CalcColors()
{
// take data from m_CurrentFrameHeader and m_pCurrentFramePixels .. process for atmo ...
tHSVColor HSV_Img[IMAGE_SIZE];
tRGBColor pixelColor;
int srcIndex,index = 0;
memset(&HSV_Img,0,sizeof(HSV_Img));
// msg_Dbg( m_pLog, "CalcColors start...");
if((m_CurrentFrameHeader.biWidth == CAP_WIDTH) && (m_CurrentFrameHeader.biHeight == CAP_HEIGHT))
{
// HSVI = HSV Image allready in right format just copy the easiest task
// und weiterverarbeiten lassen
#ifdef _ATMO_VLC_PLUGIN_
if(m_CurrentFrameHeader.biCompression == VLC_FOURCC('H','S','V','I'))
#else
if(m_CurrentFrameHeader.biCompression == MakeDword('H','S','V','I'))
#endif
{
memcpy( &HSV_Img, m_pCurrentFramePixels, CAP_WIDTH * CAP_HEIGHT * sizeof(tHSVColor));
}
else if(m_CurrentFrameHeader.biCompression == BI_RGB)
{
if(m_CurrentFrameHeader.biBitCount == 16)
{
unsigned short *buffer = (unsigned short *)m_pCurrentFramePixels;
for(int y=0;y<CAP_HEIGHT;y++)
{
srcIndex = y * CAP_WIDTH;
for(int x=0;x<CAP_WIDTH;x++)
{
pixelColor.b = (buffer[srcIndex] & 31) << 3;
pixelColor.g = ((buffer[srcIndex] >> 5) & 31) << 3;
pixelColor.r = ((buffer[srcIndex] >> 10) & 63) << 2;
srcIndex++;
HSV_Img[index++] = RGB2HSV(pixelColor);
}
}
}
else if(m_CurrentFrameHeader.biBitCount == 24)
{
for(int y=0;y<CAP_HEIGHT;y++)
{
srcIndex = y * (CAP_WIDTH*3);
for(int x=0;x<CAP_WIDTH;x++)
{
pixelColor.b = ((unsigned char *)m_pCurrentFramePixels)[srcIndex++];
pixelColor.g = ((unsigned char *)m_pCurrentFramePixels)[srcIndex++];
pixelColor.r = ((unsigned char *)m_pCurrentFramePixels)[srcIndex++];
HSV_Img[index++] = RGB2HSV(pixelColor);
}
}
}
else if(m_CurrentFrameHeader.biBitCount == 32)
{
for(int y=0;y<CAP_HEIGHT;y++)
{
srcIndex = y * (CAP_WIDTH*4);
for(int x=0;x<CAP_WIDTH;x++)
{
pixelColor.b = ((unsigned char *)m_pCurrentFramePixels)[srcIndex++];
pixelColor.g = ((unsigned char *)m_pCurrentFramePixels)[srcIndex++];
pixelColor.r = ((unsigned char *)m_pCurrentFramePixels)[srcIndex++];
srcIndex++;
HSV_Img[index++] = RGB2HSV(pixelColor);
}
}
}
}
}
/*
else {
if the image color format wasn't recognized - the output
will be black (memset)
}
*/
/* remove the source buffer */
free( m_pCurrentFramePixels );
m_pCurrentFramePixels = NULL;
/*
now convert the pixeldata into one RGB trippel for each channel,
this is done by some very sophisticated methods and statistics ...
the only thing I know - the pixel priority is controled by some
gradients for each edge of the picture
(sorry I don't know how it exactly works because the formulas
are done by some one else...)
*/
//msg_Dbg( m_pLog, "CalcColors ende AddPacket...");
m_pAtmoDynData->getLivePacketQueue()->AddPacket( m_pAtmoColorCalculator->AnalyzeHSV( HSV_Img ) );
//msg_Dbg( m_pLog, "CalcColors ende AddPacket...done.");
}
#ifndef _AtmoExternalCaptureInput_h_
#define _AtmoExternalCaptureInput_h_
#include "AtmoDefs.h"
#if defined(_WIN32)
# include <windows.h>
# else
# if defined(_ATMO_VLC_PLUGIN_)
// need bitmap info header
# include <vlc_codecs.h>
# endif
#endif
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc_common.h>
# include <vlc_threads.h>
#endif
#include "AtmoInput.h"
#include "AtmoThread.h"
#include "AtmoConfig.h"
#include "AtmoDynData.h"
#include "AtmoCalculations.h"
class CAtmoExternalCaptureInput : public CAtmoInput
{
protected:
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_t m_WakeupCond;
vlc_mutex_t m_WakeupLock;
vlc_object_t *m_pLog;
#else
HANDLE m_hWakeupEvent;
CRITICAL_SECTION m_BufferLock;
#endif
VLC_BITMAPINFOHEADER m_CurrentFrameHeader;
void *m_pCurrentFramePixels;
virtual DWORD Execute(void);
void CalcColors();
public:
/*
this method is called from the com server AtmoLiveViewControlImpl!
or inside videolan from the filter method to start a new processing
*/
void DeliverNewSourceDataPaket(VLC_BITMAPINFOHEADER *bmpInfoHeader,void *pixelData);
public:
CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData);
virtual ~CAtmoExternalCaptureInput(void);
/*
Opens the input-device. Parameters (e.g. the device-name)
Returns true if the input-device was opened successfully.
input-device can be the GDI surface of screen (windows only)
or the videolan filter
*/
virtual ATMO_BOOL Open(void);
/*
Closes the input-device.
Returns true if the input-device was closed successfully.
*/
virtual ATMO_BOOL Close(void);
};
#endif
/*
* AtmoInput.cpp: abstract class for retrieving precalculated image data
* from different sources in the live view mode
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "AtmoDefs.h"
#include "AtmoInput.h"
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoInput::CAtmoInput(CAtmoDynData *pAtmoDynData) : CThread(pAtmoDynData->getAtmoFilter())
{
m_pAtmoDynData = pAtmoDynData;
m_pAtmoColorCalculator = new CAtmoColorCalculator(pAtmoDynData->getAtmoConfig());
}
#else
CAtmoInput::CAtmoInput(CAtmoDynData *pAtmoDynData)
{
m_pAtmoDynData = pAtmoDynData;
m_pAtmoColorCalculator = new CAtmoColorCalculator(pAtmoDynData->getAtmoConfig());
}
#endif
CAtmoInput::~CAtmoInput(void)
{
delete m_pAtmoColorCalculator;
}
/*
* AtmoInput.h: abstract class for retrieving precalculated image data from
* different sources in the live view mode
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoInput_h_
#define _AtmoInput_h_
#include "AtmoDefs.h"
#include "AtmoCalculations.h"
#include "AtmoPacketQueue.h"
#include "AtmoThread.h"
#include "AtmoDynData.h"
class CAtmoDynData;
/*
basic definition of an AtmoLight data/image source ...
*/
class CAtmoInput : public CThread {
protected:
CAtmoDynData *m_pAtmoDynData;
CAtmoColorCalculator *m_pAtmoColorCalculator;
public:
CAtmoInput(CAtmoDynData *pAtmoDynData);
virtual ~CAtmoInput(void);
// Opens the input-device.
// Returns true if the input-device was opened successfully.
virtual ATMO_BOOL Open(void) { return ATMO_FALSE; }
// Closes the input-device.
// Returns true if the input-device was closed successfully.
virtual ATMO_BOOL Close(void) { return ATMO_FALSE; }
};
#endif
/*
* AtmoLiveView.cpp: this effect outputs colors as result of a picture
* content (most complex effect) see thread.c of the linux VDR version -
* to fully understand what happens here..
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "AtmoDefs.h"
#include "AtmoLiveView.h"
#include "AtmoOutputFilter.h"
#include "AtmoTools.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc_common.h>
#else
# include "AtmoGdiDisplayCaptureInput.h"
#endif
#include "AtmoExternalCaptureInput.h"
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData) :
CThread(pAtmoDynData->getAtmoFilter())
{
this->m_pAtmoDynData = pAtmoDynData;
}
#else
CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData)
{
this->m_pAtmoDynData = pAtmoDynData;
}
#endif
CAtmoLiveView::~CAtmoLiveView(void)
{
}
DWORD CAtmoLiveView::Execute(void)
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_object_t *m_pLog = m_pAtmoDynData->getAtmoFilter();
mtime_t ticks;
mtime_t t;
mtime_t packet_time;
#else
DWORD ticks;
DWORD t;
DWORD packet_time;
#endif
int i_frame_counter = -1;
pColorPacket ColorPacket;
pColorPacket PreviousPacket = NULL;
CAtmoConnection *pAtmoConnection = this->m_pAtmoDynData->getAtmoConnection();
if((pAtmoConnection == NULL) || (pAtmoConnection->isOpen() == ATMO_FALSE)) return 0;
CAtmoConfig *pAtmoConfig = this->m_pAtmoDynData->getAtmoConfig();
/*
this object does post processing of the pixel data
like jump /scenechange detection fading over the colors
*/
CAtmoOutputFilter *filter = new CAtmoOutputFilter( this->m_pAtmoDynData->getAtmoConfig() );
CAtmoPacketQueue *pPacketQueue = this->m_pAtmoDynData->getLivePacketQueue();
int frameDelay = pAtmoConfig->getLiveView_FrameDelay();
#if defined(_ATMO_VLC_PLUGIN_)
/*
because time function of vlc are working with us values instead of ms
*/
frameDelay = frameDelay * 1000;
#endif
/*
wait for the first frame to go in sync with the other thread
*/
t = get_time;
if( pPacketQueue->WaitForNextPacket(3000) )
{
if( frameDelay > 0 )
do_sleep( frameDelay );
#if defined(_ATMO_VLC_PLUGIN_)
msg_Dbg( m_pLog, "First Packet got %" PRId64 " ms", (get_time - t) / 1000 );
#endif
}
while(this->m_bTerminated == ATMO_FALSE)
{
i_frame_counter++;
if(i_frame_counter == 50) i_frame_counter = 0;
/* grab current Packet from InputQueue (working as FIFO)! */
#if defined(_ATMO_VLC_PLUGIN_)
ColorPacket = pPacketQueue->GetNextPacket(get_time - frameDelay, (i_frame_counter == 0), m_pLog, packet_time);
#else
ColorPacket = pPacketQueue->GetNextPacket(get_time - frameDelay, (i_frame_counter == 0), packet_time);
#endif
if(ColorPacket)
{
/*
create a packet copy - for later reuse if the input is slower than 25fps
*/
if(PreviousPacket && (PreviousPacket->numColors == ColorPacket->numColors))
CopyColorPacket(ColorPacket, PreviousPacket)
else {
delete [] PreviousPacket;
DupColorPacket(PreviousPacket, ColorPacket )
}
} else {
/*
packet queue was empty for the given point of time
*/
if(i_frame_counter == 0)
{
#if defined(_ATMO_VLC_PLUGIN_)
msg_Dbg( m_pLog, "wait for delayed packet..." );
#endif
t = get_time;
if( pPacketQueue->WaitForNextPacket(200) )
{
if( frameDelay > 0 )
do_sleep( frameDelay );
#if defined(_ATMO_VLC_PLUGIN_)
msg_Dbg( m_pLog, "got delayed packet %" PRId64 " ms", (mdate() - t) / 1000 );
#endif
continue;
}
}
/*
reuse previous color packet
*/
DupColorPacket(ColorPacket, PreviousPacket)
}
ticks = get_time;
if(ColorPacket)
{
/* pass it through the outputfilters! */
// Info Filtering will possible free the colorpacket and alloc a new one!
ColorPacket = filter->Filtering(ColorPacket);
/* apply gamma correction - only if the hardware isnt capable doing this */
ColorPacket = CAtmoTools::ApplyGamma(pAtmoConfig, ColorPacket);
/*
apply white calibration - only if it is not
done by the hardware
*/
if(pAtmoConfig->isUseSoftwareWhiteAdj())
ColorPacket = CAtmoTools::WhiteCalibration(pAtmoConfig, ColorPacket);
/* send color data to the the hardware... */
pAtmoConnection->SendData(ColorPacket);
delete (char *)ColorPacket;
}
/*
calculate RunTime of thread abbove (doesn't work well - so
this threads comes out of sync with Image producer and the
framerate (25fps) drifts away
*/
#if defined(_ATMO_VLC_PLUGIN_)
ticks = ((mdate() - ticks) + 999)/1000;
#else
ticks = GetTickCount() - ticks;
#endif
if(ticks < 40)
{
if( ThreadSleep( 40 - ticks ) == ATMO_FALSE )
break;
}
}
#if defined(_ATMO_VLC_PLUGIN_)
msg_Dbg( m_pLog, "DWORD CAtmoLiveView::Execute(void) terminates");
pPacketQueue->ShowQueueStatus( m_pLog );
#endif
delete [] PreviousPacket;
delete filter;
return 0;
}
/*
* AtmoLiveView.h: this effect outputs colors as result of a picture content
* (most complex effect) see thread.c of the linux version - to fully understand
* what happes here..
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoLiveView_h_
#define _AtmoLiveView_h_
#include "AtmoDefs.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include <windows.h>
#endif
#include "AtmoThread.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#include "AtmoInput.h"
class CAtmoLiveView : public CThread
{
protected:
virtual DWORD Execute(void);
protected:
CAtmoDynData *m_pAtmoDynData;
public:
CAtmoLiveView(CAtmoDynData *pAtmoDynData);
virtual ~CAtmoLiveView(void);
};
#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
/*
* AtmoOutputFilter.cpp: Post Processor for the color data retrieved from
* a CAtmoInput
*
* mostly 1:1 from vdr-linux-src "filter.c" copied
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include "AtmoOutputFilter.h"
CAtmoOutputFilter::CAtmoOutputFilter(CAtmoConfig *atmoConfig )
{
this->m_pAtmoConfig = atmoConfig;
this->m_percent_filter_output_old = NULL;
this->m_mean_filter_output_old = NULL;
this->m_mean_values = NULL;
this->m_mean_sums = NULL;
ResetFilter();
}
CAtmoOutputFilter::~CAtmoOutputFilter(void)
{
if(m_percent_filter_output_old)
delete[] m_percent_filter_output_old;
if(m_mean_filter_output_old)
delete[] m_mean_filter_output_old;
if(m_mean_values)
delete[] m_mean_values;
if(m_mean_sums)
delete[] m_mean_sums;
}
void CAtmoOutputFilter::ResetFilter(void)
{
// reset filter values
MeanFilter(NULL, true);
PercentFilter(NULL, true);
}
pColorPacket CAtmoOutputFilter::Filtering(pColorPacket ColorPacket)
{
switch (m_pAtmoConfig->getLiveViewFilterMode())
{
case afmNoFilter:
return ColorPacket;
break;
case afmCombined:
return MeanFilter(ColorPacket, false);
break;
case afmPercent:
return PercentFilter(ColorPacket, false);
break;
}
return ColorPacket;
}
pColorPacket CAtmoOutputFilter::PercentFilter(pColorPacket filter_input, ATMO_BOOL init)
{
// last values needed for the percentage filter
if (init) // Initialization
{
if(m_percent_filter_output_old)
delete[] m_percent_filter_output_old;
m_percent_filter_output_old = NULL;
return(NULL);
}
if(!m_percent_filter_output_old || (m_percent_filter_output_old->numColors!=filter_input->numColors)) {
delete[] m_percent_filter_output_old;
AllocColorPacket(m_percent_filter_output_old, filter_input->numColors);
ZeroColorPacket(m_percent_filter_output_old);
}
int percentNew = this->m_pAtmoConfig->getLiveViewFilter_PercentNew();
pColorPacket filter_output;
AllocColorPacket(filter_output, filter_input->numColors);
for (int zone = 0; zone < filter_input->numColors; zone++)
{
filter_output->zone[zone].r = (filter_input->zone[zone].r *
(100-percentNew) + m_percent_filter_output_old->zone[zone].r * percentNew) / 100;
filter_output->zone[zone].g = (filter_input->zone[zone].g *
(100-percentNew) + m_percent_filter_output_old->zone[zone].g * percentNew) / 100;
filter_output->zone[zone].b = (filter_input->zone[zone].b *
(100-percentNew) + m_percent_filter_output_old->zone[zone].b * percentNew) / 100;
}
CopyColorPacket( filter_output, m_percent_filter_output_old );
delete[] filter_input;
return filter_output;
}
pColorPacket CAtmoOutputFilter::MeanFilter(pColorPacket filter_input, ATMO_BOOL init)
{
// needed vor the running mean value filter
// needed for the percentage filter
static int filter_length_old;
char reinitialize = 0;
long int tmp;
pColorPacket filter_output;
if (init) // Initialization
{
if(m_mean_filter_output_old)
delete[] m_mean_filter_output_old;
m_mean_filter_output_old = NULL;
if(m_mean_values)
delete[] m_mean_values;
m_mean_values = NULL;
if(m_mean_sums)
delete[] m_mean_sums;
m_mean_sums = NULL;
return (NULL);
}
if(!m_mean_filter_output_old || (m_mean_filter_output_old->numColors!=filter_input->numColors)) {
delete[] m_mean_filter_output_old;
AllocColorPacket(m_mean_filter_output_old, filter_input->numColors);
ZeroColorPacket(m_mean_filter_output_old);
}
if(!m_mean_values || (m_mean_values->numColors!=filter_input->numColors)) {
delete[] m_mean_values;
AllocColorPacket(m_mean_values, filter_input->numColors);
ZeroColorPacket(m_mean_values);
}
if(!m_mean_sums || (m_mean_sums->numColors!=filter_input->numColors)) {
delete[] m_mean_sums;
AllocLongColorPacket(m_mean_sums, filter_input->numColors);
ZeroLongColorPacket(m_mean_sums);
}
AllocColorPacket(filter_output, filter_input->numColors);
int AtmoSetup_Filter_MeanLength = m_pAtmoConfig->getLiveViewFilter_MeanLength();
int AtmoSetup_Filter_PercentNew = m_pAtmoConfig->getLiveViewFilter_PercentNew();
int AtmoSetup_Filter_MeanThreshold = m_pAtmoConfig->getLiveViewFilter_MeanThreshold();
// if filter_length has changed
if (filter_length_old != AtmoSetup_Filter_MeanLength)
{
// force reinitialization of the filter
reinitialize = 1;
}
filter_length_old = AtmoSetup_Filter_MeanLength;
if (filter_length_old < 20) filter_length_old = 20; // avoid division by 0
for (int zone = 0; zone < filter_input->numColors; zone++)
{
// calculate the mean-value filters
m_mean_sums->longZone[zone].r +=
(long int)(filter_input->zone[zone].r - m_mean_values->zone[zone].r); // red
tmp = m_mean_sums->longZone[zone].r / ((long int)filter_length_old / 20);
if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
m_mean_values->zone[zone].r = (unsigned char)tmp;
m_mean_sums->longZone[zone].g +=
(long int)(filter_input->zone[zone].g - m_mean_values->zone[zone].g); // green
tmp = m_mean_sums->longZone[zone].g / ((long int)filter_length_old / 20);
if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
m_mean_values->zone[zone].g = (unsigned char)tmp;
m_mean_sums->longZone[zone].b +=
(long int)(filter_input->zone[zone].b - m_mean_values->zone[zone].b); // blue
tmp = m_mean_sums->longZone[zone].b / ((long int)filter_length_old / 20);
if(tmp<0) tmp = 0; else { if(tmp>255) tmp = 255; }
m_mean_values->zone[zone].b = (unsigned char)tmp;
// check, if there is a jump -> check if differences between actual values and filter values are too big
long int dist; // distance between the two colors in the 3D RGB space
dist = (m_mean_values->zone[zone].r - filter_input->zone[zone].r) *
(m_mean_values->zone[zone].r - filter_input->zone[zone].r) +
(m_mean_values->zone[zone].g - filter_input->zone[zone].g) *
(m_mean_values->zone[zone].g - filter_input->zone[zone].g) +
(m_mean_values->zone[zone].b - filter_input->zone[zone].b) *
(m_mean_values->zone[zone].b - filter_input->zone[zone].b);
/*
if (dist > 0) { dist = (long int)sqrt((double)dist); }
avoid sqrt(0) (TODO: necessary?)
I think its cheaper to calculate the square of something ..? insteas geting the square root?
*/
double distMean = ((double)AtmoSetup_Filter_MeanThreshold * 3.6f);
distMean = distMean * distMean;
/*
compare calculated distance with the filter threshold
if ((dist > (long int)((double)AtmoSetup.Filter_MeanThreshold * 3.6f)) || ( reinitialize == 1))
*/
if ((dist > distMean) || ( reinitialize == 1))
{
// filter jump detected -> set the long filters to the result of the short filters
filter_output->zone[zone] = m_mean_values->zone[zone] = filter_input->zone[zone];
m_mean_sums->longZone[zone].r = filter_input->zone[zone].r *
(filter_length_old / 20);
m_mean_sums->longZone[zone].g = filter_input->zone[zone].g *
(filter_length_old / 20);
m_mean_sums->longZone[zone].b = filter_input->zone[zone].b *
(filter_length_old / 20);
}
else
{
// apply an additional percent filter and return calculated values
filter_output->zone[zone].r = (m_mean_values->zone[zone].r *
(100-AtmoSetup_Filter_PercentNew) +
m_mean_filter_output_old->zone[zone].r * AtmoSetup_Filter_PercentNew) / 100;
filter_output->zone[zone].g = (m_mean_values->zone[zone].g *
(100-AtmoSetup_Filter_PercentNew) +
m_mean_filter_output_old->zone[zone].g * AtmoSetup_Filter_PercentNew) / 100;
filter_output->zone[zone].b = (m_mean_values->zone[zone].b *
(100-AtmoSetup_Filter_PercentNew) +
m_mean_filter_output_old->zone[zone].b * AtmoSetup_Filter_PercentNew) / 100;
}
}
CopyColorPacket(filter_output, m_mean_filter_output_old);
delete[] filter_input;
return(filter_output);
}
/*
* AtmoOutputFilter.h: Post Processor for the color data retrieved from a CAtmoInput
*
* mostly 1:1 from Linux-src "filter.c" copied
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoOutputFilter_h_
#define _AtmoOutputFilter_h_
#include "AtmoConfig.h"
#include "AtmoDefs.h"
class CAtmoOutputFilter
{
private:
//tColorPacket filter_input; // input of the filter wozu?
//tColorPacket filter_output; // output of the filter
pColorPacket m_percent_filter_output_old;
pColorPacket m_mean_filter_output_old;
pColorPacket m_mean_values;
pColorPacketLongInt m_mean_sums;
pColorPacket PercentFilter(pColorPacket filter_input, ATMO_BOOL init);
pColorPacket MeanFilter(pColorPacket filter_input, ATMO_BOOL init);
CAtmoConfig *m_pAtmoConfig;
public:
public:
CAtmoOutputFilter(CAtmoConfig *atmoConfig);
virtual ~CAtmoOutputFilter(void);
void ResetFilter(void);
pColorPacket Filtering(pColorPacket ColorPacket);
};
#endif
This diff is collapsed.
/*
* 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(vlc_object_t *p_this);
pColorPacket GetNextPacket(mtime_t timecode, ATMO_BOOL withWait, vlc_object_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
This diff is collapsed.
/*
* AtmoThread.h: Base thread class for all threads inside AtmoWin
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoThread_h_
#define _AtmoThread_h_
#include "AtmoDefs.h"
#if defined(_ATMO_VLC_PLUGIN_)
// use threading stuff from videolan!
# include <vlc_common.h>
# include <vlc_threads.h>
#else
# include <windows.h>
#endif
class CThread
{
protected:
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_t m_TerminateLock;
vlc_cond_t m_TerminateCond;
vlc_object_t *m_pOwner;
ATMO_BOOL m_HasThread;
vlc_thread_t m_Thread;
#else
HANDLE m_hThread;
DWORD m_dwThreadID;
HANDLE m_hTerminateEvent;
#endif
volatile ATMO_BOOL m_bTerminated;
private:
#if defined(_ATMO_VLC_PLUGIN_)
static void *ThreadProc(void *);
#else
static DWORD WINAPI ThreadProc(LPVOID lpParameter);
#endif
protected:
virtual DWORD Execute(void);
ATMO_BOOL ThreadSleep(DWORD millisekunden);
public:
#if defined(_ATMO_VLC_PLUGIN_)
CThread(vlc_object_t *pOwner);
#else
CThread(void);
#endif
virtual ~CThread(void);
void Terminate(void);
void Run();
};
#endif
This diff is collapsed.
/*
* AtmoTools.h: Collection of tool and helperfunction
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoTools_h_
#define _AtmoTools_h_
#include "AtmoDefs.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#include "AtmoDynData.h"
/*
implements some tool functions - for use in different classes - and cases!
to avoid copy and paste code ...
*/
class CAtmoTools
{
private:
CAtmoTools(void);
~CAtmoTools(void);
public:
static EffectMode SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode);
static LivePictureSource SwitchLiveSource(CAtmoDynData *pDynData, LivePictureSource newLiveSource);
static void ShowShutdownColor(CAtmoDynData *pDynData);
static ATMO_BOOL RecreateConnection(CAtmoDynData *pDynData);
static pColorPacket WhiteCalibration(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket);
static pColorPacket ApplyGamma(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket);
static int SetChannelAssignment(CAtmoDynData *pDynData, int index);
#if !defined(_ATMO_VLC_PLUGIN_)
static void SaveBitmap(HDC hdc,HBITMAP hBmp,char *fileName);
#endif
};
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* DmxTools.h: functions to convert , or ; separated 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.
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