atmo.cpp
资源名称:vlc-1.0.5.zip [点击查看]
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:83k
源码类别:
midi
开发平台:
Unix_Linux
- /*****************************************************************************
- * atmo.cpp : "Atmo Light" video filter
- *****************************************************************************
- * Copyright (C) 2000-2006 the VideoLAN team
- * $Id: 2e78693a616aadcc9dc6a879569ab2a46f25f8d2 $
- *
- * Authors: André Weber (WeberAndre@gmx.de)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
- /*****************************************************************************
- * Preamble
- *****************************************************************************/
- #include <stdlib.h> /* malloc(), free() */
- #include <string.h>
- #include <math.h> /* sin(), cos() */
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
- // #define __ATMO_DEBUG__
- // [:Zs]+$
- #include <vlc_common.h>
- #include <vlc_plugin.h>
- #include <vlc_vout.h>
- #include <vlc_playlist.h>
- #include "vlc_filter.h"
- #include "AtmoDefs.h"
- #include "AtmoDynData.h"
- #include "AtmoLiveView.h"
- #include "AtmoTools.h"
- #include "AtmoExternalCaptureInput.h"
- #include "AtmoConfig.h"
- #include "AtmoConnection.h"
- #include "AtmoSerialConnection.h"
- /*****************************************************************************
- * Local prototypes
- *****************************************************************************/
- /* directly to vlc related functions required that the module is accepted */
- static int CreateFilter ( vlc_object_t * );
- static void DestroyFilter ( vlc_object_t * );
- static picture_t * Filter( filter_t *, picture_t *);
- /* callback for global variable state pause / continue / stop events */
- static void AddStateVariableCallback( filter_t *);
- static void DelStateVariableCallback( filter_t *);
- static int StateCallback(vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void *);
- /* callback for variable crop-update */
- static void AddCropVariableCallback( filter_t *);
- static void DelCropVariableCallback( filter_t *);
- static int CropCallback(vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void *);
- /* callback for atmo settings variables whose change
- should be immediately realized and applied to output
- */
- static void DelAtmoSettingsVariablesCallbacks(filter_t *);
- static void AddAtmoSettingsVariablesCallbacks(filter_t *);
- static int AtmoSettingsCallback(vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void *);
- #if defined(__ATMO_DEBUG__)
- static void atmo_parse_crop(char *psz_cropconfig,
- video_format_t fmt_in,
- video_format_t fmt_render,
- int &i_visible_width,
- int &i_visible_height,
- int &i_x_offset,
- int &i_y_offset );
- #endif
- /* function to shutdown the fade thread which is started on pause*/
- static void CheckAndStopFadeThread(filter_t *);
- /* extracts a small RGB (BGR) Image from an YUV image */
- static void ExtractMiniImage_YUV(filter_sys_t *, picture_t *, uint8_t *);
- #if defined(__ATMO_DEBUG__)
- void SaveBitmap(filter_sys_t *p_sys, uint8_t *p_pixels, char *psz_filename);
- #endif
- /*****************************************************************************
- * External Prototypes for the AtmoCtrlLib.DLL
- *****************************************************************************/
- /*
- * if effectmode = emLivePicture then the source could be GDI (Screencapture)
- * or External - this means another application delivers Pixeldata to AtmoWin
- * Clientsoftware through AtmoCtrlLib.DLL and the COM Api
- */
- #define lvsGDI 0
- #define lvsExternal 1
- /*
- strings for settings menus and hints
- */
- #define MODULE_DESCRIPTION N_ (
- "This module allows to control an so called AtmoLight device "
- "connected to your computer.n"
- "AtmoLight is the homegrown version of what Philips calls AmbiLight.n"
- "If you need further information feel free to visit us atnn"
- "http://www.vdr-wiki.de/wiki/index.php/Atmo-pluginn "
- "http://www.vdr-wiki.de/wiki/index.php/AtmoWinnn"
- "You can find there detailed descriptions on how to build it for yourself "
- "and where to get the required parts.n"
- "You can also have a look at pictures and some movies showing such a device "
- "in live action.")
- #if defined( __ATMO_DEBUG__ )
- # define SAVEFRAMES_TEXT N_("Save Debug Frames")
- # define SAVEFRAMES_LONGTEXT N_("Write every 128th miniframe to a folder.")
- # define FRAMEPATH_TEXT N_("Debug Frame Folder")
- # define FRAMEPATH_LONGTEXT N_("The path where the debugframes "
- "should be saved")
- #endif
- #define WIDTH_TEXT N_("Extracted Image Width")
- #define WIDTH_LONGTEXT N_("The width of the mini image for "
- "further processing (64 is default)")
- #define HEIGHT_TEXT N_("Extracted Image Height")
- #define HEIGHT_LONGTEXT N_("The height of the mini image for "
- "further processing (48 is default)")
- #define PCOLOR_TEXT N_("Color when paused")
- #define PCOLOR_LONGTEXT N_("Set the color to show if the user "
- "pauses the video. (Have light to get "
- "another beer?)")
- #define PCOLOR_RED_TEXT N_("Pause-Red")
- #define PCOLOR_RED_LONGTEXT N_("Red component of the pause color")
- #define PCOLOR_GREEN_TEXT N_("Pause-Green")
- #define PCOLOR_GREEN_LONGTEXT N_("Green component of the pause color")
- #define PCOLOR_BLUE_TEXT N_("Pause-Blue")
- #define PCOLOR_BLUE_LONGTEXT N_("Blue component of the pause color")
- #define FADESTEPS_TEXT N_("Pause-Fadesteps")
- #define FADESTEPS_LONGTEXT N_("Number of steps to change current color "
- "to pause color (each step takes 40ms)")
- #define ECOLOR_RED_TEXT N_("End-Red")
- #define ECOLOR_RED_LONGTEXT N_("Red component of the shutdown color")
- #define ECOLOR_GREEN_TEXT N_("End-Green")
- #define ECOLOR_GREEN_LONGTEXT N_("Green component of the shutdown color")
- #define ECOLOR_BLUE_TEXT N_("End-Blue")
- #define ECOLOR_BLUE_LONGTEXT N_("Blue component of the shutdown color")
- #define EFADESTEPS_TEXT N_("End-Fadesteps")
- #define EFADESTEPS_LONGTEXT N_("Number of steps to change current color to "
- "end color for dimming up the light in cinema "
- "style... (each step takes 40ms)")
- #define USEWHITEADJ_TEXT N_("Use Software White adjust")
- #define USEWHITEADJ_LONGTEXT N_("Should the buildin driver do a white "
- "adjust or your LED stripes? recommend.")
- #define WHITE_RED_TEXT N_("White Red")
- #define WHITE_RED_LONGTEXT N_("Red value of a pure white on your "
- "LED stripes.")
- #define WHITE_GREEN_TEXT N_("White Green")
- #define WHITE_GREEN_LONGTEXT N_("Green value of a pure white on your "
- "LED stripes.")
- #define WHITE_BLUE_TEXT N_("White Blue")
- #define WHITE_BLUE_LONGTEXT N_("Blue value of a pure white on your "
- "LED stripes.")
- #define SERIALDEV_TEXT N_("Serial Port/Device")
- #define SERIALDEV_LONGTEXT N_("Name of the serial port where the AtmoLight "
- "controller is attached to.n"
- "On Windows usually something like COM1 or "
- "COM2. On Linux /dev/ttyS01 f.e.")
- #define EDGE_TEXT N_("Edge Weightning")
- #define EDGE_LONGTEXT N_("Increasing this value will result in color "
- "more depending on the border of the frame.")
- #define BRIGHTNESS_TEXT N_("Brightness")
- #define BRIGHTNESS_LONGTEXT N_("Overall brightness of your LED stripes")
- #define DARKNESS_TEXT N_("Darkness Limit")
- #define DARKNESS_LONGTEXT N_("Pixels with a saturation lower than this will "
- "be ignored. Should be greater than one for "
- "letterboxed videos.")
- #define HUEWINSIZE_TEXT N_("Hue windowing")
- #define HUEWINSIZE_LONGTEXT N_("Used for statistics.")
- #define SATWINSIZE_TEXT N_("Sat windowing")
- #define SATWINSIZE_LONGTEXT N_("Used for statistics.")
- #define MEANLENGTH_TEXT N_("Filter length (ms)")
- #define MEANLENGTH_LONGTEXT N_("Time it takes until a color is completely "
- "changed. This prevents flickering.")
- #define MEANTHRESHOLD_TEXT N_("Filter threshold")
- #define MEANTHRESHOLD_LONGTEXT N_("How much a color has to be changed for an "
- "immediate color change.")
- #define MEANPERCENTNEW_TEXT N_("Filter Smoothness (in %)")
- #define MEANPERCENTNEW_LONGTEXT N_("Filter Smoothness")
- /* FIXME: WTF?!! feepk, July 6 '08 */
- #define FILTERMODE_TEXT N_("Filter mode")
- #define FILTERMODE_LONGTEXT N_("kind of filtering which should be use to "
- "calcuate the color output")
- static const int pi_filtermode_values[] = {
- (int)afmNoFilter,
- (int)afmCombined,
- (int)afmPercent
- };
- static const char *const ppsz_filtermode_descriptions[] = {
- N_("No Filtering"),
- N_("Combined"),
- N_("Percent")
- };
- #define FRAMEDELAY_TEXT N_("Frame delay")
- #define FRAMEDELAY_LONGTEXT N_("Helps to get the video output and the light "
- "effects in sync. Values around 20ms should "
- "do the trick.")
- #define CHANNEL_0_ASSIGN_TEXT N_("Channel summary")
- #define CHANNEL_1_ASSIGN_TEXT N_("Channel left")
- #define CHANNEL_2_ASSIGN_TEXT N_("Channel right")
- #define CHANNEL_3_ASSIGN_TEXT N_("Channel top")
- #define CHANNEL_4_ASSIGN_TEXT N_("Channel bottom")
- #define CHANNELASSIGN_LONGTEXT N_("Maps the hardware channel X to logical "
- "channel Y to fix wrong wiring :-)")
- static const int pi_channel_assignment_values[] = {
- -1,
- 0,
- 1,
- 2,
- 3,
- 4
- };
- static const char *const ppsz_channel_assignment_descriptions[] = {
- N_("disabled"),
- N_("summary"),
- N_("left"),
- N_("right"),
- N_("top"),
- N_("bottom")
- };
- #define ZONE_0_GRADIENT_TEXT N_("Summary gradient")
- #define ZONE_1_GRADIENT_TEXT N_("Left gradient")
- #define ZONE_2_GRADIENT_TEXT N_("Right gradient")
- #define ZONE_3_GRADIENT_TEXT N_("Top gradient")
- #define ZONE_4_GRADIENT_TEXT N_("Bottom gradient")
- #define ZONE_X_GRADIENT_LONG_TEXT N_("Defines a small bitmap with 64x48 "
- "pixels, containing a grayscale gradient")
- #if defined( WIN32 )
- # define ATMOWINEXE_TEXT N_("Filename of AtmoWinA.exe")
- # define ATMOWINEXE_LONGTEXT N_("if you want the AtmoLight control "
- "software to be launched by VLC, enter the "
- "complete path of AtmoWinA.exe here.")
- # define USEBUILDIN_TEXT N_("Use built-in AtmoLight")
- # define USEBUILDIN_LONGTEXT N_("VLC will directly use your AtmoLight "
- "hardware without running the external "
- "AtmoWinA.exe Userspace driver.")
- #endif
- #define CFG_PREFIX "atmo-"
- /*****************************************************************************
- * Module descriptor
- *****************************************************************************/
- vlc_module_begin ()
- set_description( N_("AtmoLight Filter") )
- set_help( MODULE_DESCRIPTION )
- set_shortname( N_( "AtmoLight" ))
- set_capability( "video filter2", 0 )
- set_category( CAT_VIDEO )
- set_subcategory( SUBCAT_VIDEO_VFILTER )
- #if defined(WIN32)
- set_section( N_("Choose between the built-in AtmoLight "
- "driver or the external" ), 0 )
- /*
- only on win32 exists the option to use the buildin driver or
- the more flexible external driver application
- */
- add_bool(CFG_PREFIX "usebuildin", true, NULL,
- USEBUILDIN_TEXT, USEBUILDIN_LONGTEXT, false)
- add_string(CFG_PREFIX "serialdev", "COM1", NULL,
- SERIALDEV_TEXT, SERIALDEV_LONGTEXT, false )
- /*
- on win32 the executeable external driver application
- for automatic start if needed
- */
- add_file(CFG_PREFIX "atmowinexe", NULL, NULL,
- ATMOWINEXE_TEXT, ATMOWINEXE_LONGTEXT, false )
- #else
- set_section( N_("Enter the connection of your AtmoLight hardware" ), 0 )
- add_string(CFG_PREFIX "serialdev", "/dev/ttyS01", NULL,
- SERIALDEV_TEXT, SERIALDEV_LONGTEXT, false )
- #endif
- /*
- color which is showed if you want durring pausing
- your movie ... used for both buildin / external
- */
- set_section( N_("Illuminate the room with this color on pause" ), 0 )
- add_bool(CFG_PREFIX "usepausecolor", false, NULL,
- PCOLOR_TEXT, PCOLOR_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "pcolor-red", 0, 0, 255, NULL,
- PCOLOR_RED_TEXT, PCOLOR_RED_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "pcolor-green", 0, 0, 255, NULL,
- PCOLOR_GREEN_TEXT, PCOLOR_GREEN_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "pcolor-blue", 192, 0, 255, NULL,
- PCOLOR_BLUE_TEXT, PCOLOR_BLUE_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "fadesteps", 50, 1, 250, NULL,
- FADESTEPS_TEXT, FADESTEPS_LONGTEXT, false)
- /*
- color which is showed if you finished watching your movie ...
- used for both buildin / external
- */
- set_section( N_("Illuminate the room with this color on shutdown" ), 0 )
- add_integer_with_range(CFG_PREFIX "ecolor-red", 192, 0, 255, NULL,
- ECOLOR_RED_TEXT, ECOLOR_RED_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "ecolor-green", 192, 0, 255, NULL,
- ECOLOR_GREEN_TEXT, ECOLOR_GREEN_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "ecolor-blue", 192, 0, 255, NULL,
- ECOLOR_BLUE_TEXT, ECOLOR_BLUE_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "efadesteps", 50, 1, 250, NULL,
- EFADESTEPS_TEXT, EFADESTEPS_LONGTEXT, false)
- /*
- settings only for the buildin driver (if external driver app is used
- these parameters are ignored.)
- definition of parameters for the buildin filter ...
- */
- set_section( N_("Settings for the built-in Live Video Processor only" ), 0 )
- add_integer_with_range(CFG_PREFIX "EdgeWeightning", 8, 1, 30, NULL,
- EDGE_TEXT, EDGE_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "Brightness", 100, 50, 300, NULL,
- BRIGHTNESS_TEXT, BRIGHTNESS_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "DarknessLimit", 5, 0, 10, NULL,
- DARKNESS_TEXT, DARKNESS_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "HueWinSize", 3, 0, 5, NULL,
- HUEWINSIZE_TEXT, HUEWINSIZE_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "SatWinSize", 3, 0, 5, NULL,
- SATWINSIZE_TEXT, SATWINSIZE_LONGTEXT, false)
- add_integer(CFG_PREFIX "filtermode", (int)afmCombined, NULL,
- FILTERMODE_TEXT, FILTERMODE_LONGTEXT, false )
- change_integer_list(pi_filtermode_values, ppsz_filtermode_descriptions, NULL )
- add_integer_with_range(CFG_PREFIX "MeanLength", 300, 300, 5000, NULL,
- MEANLENGTH_TEXT, MEANLENGTH_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "MeanThreshold", 40, 1, 100, NULL,
- MEANTHRESHOLD_TEXT, MEANTHRESHOLD_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "PercentNew", 50, 1, 100, NULL,
- MEANPERCENTNEW_TEXT, MEANPERCENTNEW_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "FrameDelay", 18, 0, 35, NULL,
- FRAMEDELAY_TEXT, FRAMEDELAY_LONGTEXT, false)
- /*
- output channel reordering
- */
- set_section( N_("Change channel assignment (fixes wrong wiring)" ), 0 )
- add_integer( CFG_PREFIX "channel_0", 0, NULL,
- CHANNEL_0_ASSIGN_TEXT, CHANNELASSIGN_LONGTEXT, false )
- change_integer_list( pi_channel_assignment_values,
- ppsz_channel_assignment_descriptions, 0 )
- add_integer( CFG_PREFIX "channel_1", 1, NULL,
- CHANNEL_1_ASSIGN_TEXT, CHANNELASSIGN_LONGTEXT, false )
- change_integer_list( pi_channel_assignment_values,
- ppsz_channel_assignment_descriptions, 0 )
- add_integer( CFG_PREFIX "channel_2", 2, NULL,
- CHANNEL_2_ASSIGN_TEXT, CHANNELASSIGN_LONGTEXT, false )
- change_integer_list( pi_channel_assignment_values,
- ppsz_channel_assignment_descriptions, 0 )
- add_integer( CFG_PREFIX "channel_3", 3, NULL,
- CHANNEL_3_ASSIGN_TEXT, CHANNELASSIGN_LONGTEXT, false )
- change_integer_list( pi_channel_assignment_values,
- ppsz_channel_assignment_descriptions, 0 )
- add_integer( CFG_PREFIX "channel_4", 4, NULL,
- CHANNEL_4_ASSIGN_TEXT, CHANNELASSIGN_LONGTEXT, false )
- change_integer_list( pi_channel_assignment_values,
- ppsz_channel_assignment_descriptions, 0 )
- /*
- LED color white calibration
- */
- set_section( N_("Adjust the white light to your LED stripes" ), 0 )
- add_bool(CFG_PREFIX "whiteadj", true, NULL,
- USEWHITEADJ_TEXT, USEWHITEADJ_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "white-red", 255, 0, 255, NULL,
- WHITE_RED_TEXT, WHITE_RED_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "white-green", 255, 0, 255, NULL,
- WHITE_GREEN_TEXT, WHITE_GREEN_LONGTEXT, false)
- add_integer_with_range(CFG_PREFIX "white-blue", 255, 0, 255, NULL,
- WHITE_BLUE_TEXT, WHITE_BLUE_LONGTEXT, false)
- /* end of definition of parameter for the buildin filter ... part 1 */
- /*
- only for buildin (external has own definition) per default the calucation
- used linear gradients for assigning a priority to the pixel - depending
- how near they are to the border ...for changing this you can create 64x48
- Pixel BMP files - which contain your own grayscale... (you can produce funny
- effects with this...) the images MUST not compressed, should have 24-bit per
- pixel, or a simple 256 color grayscale palette
- */
- set_section( N_("Change gradients" ), 0 )
- add_file(CFG_PREFIX "gradient_zone_0", NULL, NULL,
- ZONE_0_GRADIENT_TEXT, ZONE_X_GRADIENT_LONG_TEXT, true )
- add_file(CFG_PREFIX "gradient_zone_1", NULL, NULL,
- ZONE_1_GRADIENT_TEXT, ZONE_X_GRADIENT_LONG_TEXT, true )
- add_file(CFG_PREFIX "gradient_zone_2", NULL, NULL,
- ZONE_2_GRADIENT_TEXT, ZONE_X_GRADIENT_LONG_TEXT, true )
- add_file(CFG_PREFIX "gradient_zone_3", NULL, NULL,
- ZONE_3_GRADIENT_TEXT, ZONE_X_GRADIENT_LONG_TEXT, true )
- add_file(CFG_PREFIX "gradient_zone_4", NULL, NULL,
- ZONE_4_GRADIENT_TEXT, ZONE_X_GRADIENT_LONG_TEXT, true )
- #if defined(__ATMO_DEBUG__)
- add_bool(CFG_PREFIX "saveframes", false, NULL,
- SAVEFRAMES_TEXT, SAVEFRAMES_LONGTEXT, false)
- add_string(CFG_PREFIX "framepath", "", NULL,
- FRAMEPATH_TEXT, FRAMEPATH_LONGTEXT, false )
- #endif
- /*
- may be later if computers gets more power ;-) than now we increase
- the samplesize from which we do the stats for output color calculation
- */
- add_integer_with_range(CFG_PREFIX "width", 64, 64, 512, NULL,
- WIDTH_TEXT, WIDTH_LONGTEXT, true)
- add_integer_with_range(CFG_PREFIX "height", 48, 48, 384, NULL,
- HEIGHT_TEXT, HEIGHT_LONGTEXT, true)
- add_shortcut( "atmo" )
- set_callbacks( CreateFilter, DestroyFilter )
- vlc_module_end ()
- static const char *const ppsz_filter_options[] = {
- #if defined(WIN32)
- "usebuildin",
- #endif
- "serialdev",
- "EdgeWeightning",
- "Brightness",
- "DarknessLimit",
- "HueWinSize",
- "SatWinSize",
- "filtermode",
- "MeanLength",
- "MeanThreshold",
- "PercentNew",
- "FrameDelay",
- "channel_0",
- "channel_1",
- "channel_2",
- "channel_3",
- "channel_4",
- "whiteadj",
- "white-red",
- "white-green",
- "white-blue",
- "usepausecolor",
- "pcolor-red",
- "pcolor-green",
- "pcolor-blue",
- "fadesteps",
- "ecolor-red",
- "ecolor-green",
- "ecolor-blue",
- "efadesteps",
- #if defined(WIN32 )
- "usebuildin",
- "atmowinexe",
- #endif
- #if defined(__ATMO_DEBUG__)
- "saveframes" ,
- "framepath",
- #endif
- "width",
- "height",
- "gradient_zone_0",
- "gradient_zone_1",
- "gradient_zone_2",
- "gradient_zone_3",
- "gradient_zone_4",
- NULL
- };
- /*****************************************************************************
- * fadethread_t: Color Fading Thread
- *****************************************************************************
- * changes slowly the color of the output if videostream gets paused...
- *****************************************************************************
- */
- typedef struct
- {
- VLC_COMMON_MEMBERS
- filter_t *p_filter;
- /* tell the thread which color should be the target of fading */
- uint8_t ui_red;
- uint8_t ui_green;
- uint8_t ui_blue;
- /* how many steps should happen until this */
- int i_steps;
- } fadethread_t;
- static void *FadeToColorThread(vlc_object_t *);
- /*****************************************************************************
- * filter_sys_t: AtmoLight filter method descriptor
- *****************************************************************************
- * It describes the AtmoLight specific properties of an video filter.
- *****************************************************************************/
- struct filter_sys_t
- {
- /*
- special for the access of the p_fadethread member all other members
- need no special protection so far!
- */
- vlc_mutex_t filter_lock;
- bool b_enabled;
- int32_t i_AtmoOldEffect;
- bool b_pause_live;
- int32_t i_atmo_width;
- int32_t i_atmo_height;
- #if defined(__ATMO_DEBUG__)
- bool b_saveframes;
- int i_framecounter;
- char sz_framepath[MAX_PATH];
- #endif
- /* light color durring movie pause ... */
- bool b_usepausecolor;
- uint8_t ui_pausecolor_red;
- uint8_t ui_pausecolor_green;
- uint8_t ui_pausecolor_blue;
- int i_fadesteps;
- /* light color on movie finish ... */
- uint8_t ui_endcolor_red;
- uint8_t ui_endcolor_green;
- uint8_t ui_endcolor_blue;
- int i_endfadesteps;
- fadethread_t *p_fadethread;
- /* Variables for buildin driver only... */
- /* is only present and initialized if the internal driver is used*/
- CAtmoConfig *p_atmo_config;
- /* storage for temporal settings "volatile" */
- CAtmoDynData *p_atmo_dyndata;
- /* initialized for buildin driver with AtmoCreateTransferBuffers */
- BITMAPINFOHEADER mini_image_format;
- /* is only use buildin driver! */
- uint8_t *p_atmo_transfer_buffer;
- /* end buildin driver */
- /*
- contains the real output size of the video calculated on
- change event of the variable "crop" from vout
- */
- int32_t i_crop_x_offset;
- int32_t i_crop_y_offset;
- int32_t i_crop_width;
- int32_t i_crop_height;
- void (*pf_extract_mini_image) (filter_sys_t *p_sys,
- picture_t *p_inpic,
- uint8_t *p_transfer_dest);
- #if defined( WIN32 )
- /* External Library as wrapper arround COM Stuff */
- HINSTANCE h_AtmoCtrl;
- int32_t (*pf_ctrl_atmo_initialize) (void);
- void (*pf_ctrl_atmo_finalize) (int32_t what);
- int32_t (*pf_ctrl_atmo_switch_effect) (int32_t);
- int32_t (*pf_ctrl_atmo_set_live_source) (int32_t);
- void (*pf_ctrl_atmo_create_transfer_buffers) (int32_t, int32_t,
- int32_t , int32_t);
- uint8_t* (*pf_ctrl_atmo_lock_transfer_buffer) (void);
- void (*pf_ctrl_atmo_send_pixel_data) (void);
- #endif
- };
- /*
- initialize previously configured Atmo Light environment
- - if internal is enabled try to access the device on the serial port
- - if not internal is enabled and we are on win32 try to initialize
- the previously loaded DLL ...
- Return Values may be: -1 (failed for some reason - filter will be disabled)
- 1 Ok. lets rock
- */
- static int32_t AtmoInitialize(filter_t *p_filter, bool b_for_thread)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->p_atmo_config)
- {
- if(b_for_thread == false)
- {
- /* open com port */
- /* setup Output Threads ... */
- msg_Dbg( p_filter, "open serial connection %s",
- p_sys->p_atmo_config->getSerialDevice());
- if(CAtmoTools::RecreateConnection(p_sys->p_atmo_dyndata) == ATMO_TRUE)
- {
- msg_Dbg( p_filter, "start live view thread ...");
- CAtmoTools::SwitchEffect(p_sys->p_atmo_dyndata, emLivePicture);
- msg_Dbg( p_filter, "live view thread launched...");
- return 1;
- } else {
- msg_Err( p_filter,"failed to open serial device? some other software/driver may use it?");
- }
- }
- #if defined(WIN32)
- } else if(p_sys->pf_ctrl_atmo_initialize)
- {
- /* on win32 with active ctrl dll */
- return p_sys->pf_ctrl_atmo_initialize();
- #endif
- }
- return -1;
- }
- /*
- prepare the shutdown of the effect threads,
- for build in filter - close the serialport after finishing the threads...
- cleanup possible loaded DLL...
- */
- static void AtmoFinalize(filter_t *p_filter, int32_t what)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->p_atmo_config)
- {
- if(what == 1)
- {
- CAtmoDynData *p_atmo_dyndata = p_sys->p_atmo_dyndata;
- if(p_atmo_dyndata)
- {
- p_atmo_dyndata->LockCriticalSection();
- CThread *p_effect_thread = p_atmo_dyndata->getEffectThread();
- p_atmo_dyndata->setEffectThread(NULL);
- if(p_effect_thread != NULL)
- {
- /*
- forced the thread to die...
- and wait for termination of the thread
- */
- p_effect_thread->Terminate();
- delete p_effect_thread;
- msg_Dbg( p_filter, "effect thread died peacefully");
- }
- /*
- close serial port if it is open (all OS specific is inside
- CAtmoSerialConnection implemented / defined)
- */
- CAtmoConnection *p_atmo_connection =
- p_atmo_dyndata->getAtmoConnection();
- p_atmo_dyndata->setAtmoConnection(NULL);
- if(p_atmo_connection) {
- p_atmo_connection->CloseConnection();
- delete p_atmo_connection;
- }
- p_atmo_dyndata->UnLockCriticalSection();
- }
- }
- #if defined(WIN32)
- } else if(p_sys->pf_ctrl_atmo_finalize)
- {
- /* on win32 with active ctrl dll */
- p_sys->pf_ctrl_atmo_finalize(what);
- #endif
- }
- }
- /*
- switch the current light effect - does only something on win32, with the
- external libraries - if the buildin effects are used nothing happens
- */
- static int32_t AtmoSwitchEffect(filter_t *p_filter, int32_t newMode)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->p_atmo_config)
- {
- /*
- buildin driver
- doesnt know different modes for effects so this
- function call would just do nothing special
- in this case
- */
- #if defined(WIN32)
- } else if(p_sys->pf_ctrl_atmo_switch_effect)
- {
- /* on win32 with active ctrl dll */
- return p_sys->pf_ctrl_atmo_switch_effect(newMode);
- #endif
- }
- return emDisabled;
- }
- /*
- set the current live picture source, does only something on win32,
- with the external libraries - if the buildin effects are used nothing
- happens...
- */
- static int32_t AtmoSetLiveSource(filter_t *p_filter, int32_t newSource)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->p_atmo_config)
- {
- /*
- buildin driver
- doesnt know different sources so this
- function call would just do nothing special
- in this case
- */
- #if defined(WIN32)
- } else if(p_sys->pf_ctrl_atmo_set_live_source)
- {
- /* on win32 with active ctrl dll */
- return p_sys->pf_ctrl_atmo_set_live_source(newSource);
- #endif
- }
- return lvsGDI;
- }
- /*
- setup the pixel transferbuffers which is used to transfer pixeldata from
- the filter to the effect thread, and possible accross the process
- boundaries on win32, with the external DLL
- */
- static void AtmoCreateTransferBuffers(filter_t *p_filter,
- int32_t FourCC,
- int32_t bytePerPixel,
- int32_t width,
- int32_t height)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->p_atmo_config)
- {
- /*
- we need a buffer where the image is stored (only for transfer
- to the processing thread)
- */
- if(p_sys->p_atmo_transfer_buffer)
- free(p_sys->p_atmo_transfer_buffer);
- p_sys->p_atmo_transfer_buffer = (uint8_t *)malloc(bytePerPixel *
- width * height);
- memset(&p_sys->mini_image_format,0,sizeof(BITMAPINFOHEADER));
- p_sys->mini_image_format.biSize = sizeof(BITMAPINFOHEADER);
- p_sys->mini_image_format.biWidth = width;
- p_sys->mini_image_format.biHeight = height;
- p_sys->mini_image_format.biBitCount = bytePerPixel*8;
- p_sys->mini_image_format.biCompression = FourCC;
- #if defined(WIN32)
- } else if(p_sys->pf_ctrl_atmo_create_transfer_buffers)
- {
- /* on win32 with active ctrl dll */
- p_sys->pf_ctrl_atmo_create_transfer_buffers(FourCC,
- bytePerPixel,
- width,
- height);
- #endif
- }
- }
- /*
- acquire the transfer buffer pointer the buildin version only
- returns the pointer to the allocated buffer ... the
- external version on win32 has to do some COM stuff to lock the
- Variant Byte array which is behind the buffer
- */
- static uint8_t* AtmoLockTransferBuffer(filter_t *p_filter)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->p_atmo_config)
- {
- return p_sys->p_atmo_transfer_buffer;
- #if defined(WIN32)
- } else if(p_sys->pf_ctrl_atmo_lock_transfer_buffer)
- {
- /* on win32 with active ctrl dll */
- return p_sys->pf_ctrl_atmo_lock_transfer_buffer();
- #endif
- }
- return NULL;
- }
- /*
- send the content of current pixel buffer got with AtmoLockTransferBuffer
- to the processing threads
- - build in version - will forward the data to AtmoExternalCaptureInput Thread
- - win32 external - will do the same, but across the process boundaries via
- COM to the AtmoWinA.exe Process
- */
- static void AtmoSendPixelData(filter_t *p_filter)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->p_atmo_config && p_sys->p_atmo_transfer_buffer)
- {
- CAtmoDynData *p_atmo_dyndata = p_sys->p_atmo_dyndata;
- if(p_atmo_dyndata)
- {
- /*
- the cast will go Ok because we are inside videolan there is only
- this kind of effect thread implemented!
- */
- CAtmoLiveView *p_atmo_live_view_thread =
- (CAtmoLiveView *)p_atmo_dyndata->getEffectThread();
- if(p_atmo_live_view_thread)
- {
- /*
- the same as above inside videolan only this single kind of
- input exists so we can cast without further tests!
- */
- CAtmoExternalCaptureInput *p_atmo_external_capture_input_thread =
- (CAtmoExternalCaptureInput *)p_atmo_live_view_thread->getAtmoInput();
- if(p_atmo_external_capture_input_thread)
- {
- /*
- this call will do a 1:1 copy of this buffer, and wakeup
- the thread from normal sleeping
- */
- p_atmo_external_capture_input_thread->
- DeliverNewSourceDataPaket(&p_sys->mini_image_format,
- p_sys->p_atmo_transfer_buffer);
- }
- }
- }
- #if defined(WIN32)
- } else if(p_sys->pf_ctrl_atmo_send_pixel_data)
- {
- /* on win32 with active ctrl dll */
- p_sys->pf_ctrl_atmo_send_pixel_data();
- #endif
- }
- }
- /*
- Shutdown AtmoLight finally - is call from DestroyFilter
- does the cleanup restores the effectmode on the external Software
- (only win32) and possible setup the final light ...
- */
- static void Atmo_Shutdown(filter_t *p_filter)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if(p_sys->b_enabled == true)
- {
- /*
- if there is a still running show pause color thread kill him!
- */
- CheckAndStopFadeThread(p_filter);
- if(p_sys->p_atmo_config || (p_sys->i_AtmoOldEffect == emStaticColor))
- {
- /*
- fade to end color (in case of external AtmoWin Software
- assume that the static color will equal to this
- one to get a soft change and no flash!
- */
- p_sys->b_pause_live = true;
- // perpare spawn fadeing thread
- vlc_mutex_lock( &p_sys->filter_lock );
- p_sys->p_fadethread = (fadethread_t *)vlc_object_create( p_filter,
- sizeof(fadethread_t) );
- p_sys->p_fadethread->p_filter = p_filter;
- p_sys->p_fadethread->ui_red = p_sys->ui_endcolor_red;
- p_sys->p_fadethread->ui_green = p_sys->ui_endcolor_green;
- p_sys->p_fadethread->ui_blue = p_sys->ui_endcolor_blue;
- p_sys->p_fadethread->i_steps = p_sys->i_endfadesteps;
- if( vlc_thread_create( p_sys->p_fadethread,
- "AtmoLight fadeing",
- FadeToColorThread,
- VLC_THREAD_PRIORITY_LOW ) )
- {
- msg_Err( p_filter, "cannot create FadeToColorThread" );
- vlc_object_release( p_sys->p_fadethread );
- p_sys->p_fadethread = NULL;
- vlc_mutex_unlock( &p_sys->filter_lock );
- } else {
- vlc_mutex_unlock( &p_sys->filter_lock );
- /* wait for the thread... */
- vlc_thread_join(p_sys->p_fadethread);
- vlc_object_release(p_sys->p_fadethread);
- p_sys->p_fadethread = NULL;
- }
- }
- if(p_sys->i_AtmoOldEffect != emLivePicture)
- AtmoSwitchEffect(p_filter, p_sys->i_AtmoOldEffect);
- else
- AtmoSetLiveSource(p_filter, lvsGDI);
- AtmoFinalize(p_filter, 1);
- /* disable filter method .. */
- p_sys->b_enabled = false;
- }
- }
- /*
- initialize the filter_sys_t structure with the data from the settings
- variables - if the external filter on win32 is enabled try loading the DLL,
- if this fails fallback to the buildin software
- */
- static void Atmo_SetupParameters(filter_t *p_filter)
- {
- bool b_use_buildin_driver = true;
- char *psz_path;
- filter_sys_t *p_sys = p_filter->p_sys;
- /* default filter disabled until DLL loaded and Init Success!*/
- p_sys->b_enabled = false;
- /* setup default mini image size (may be later a user option) */
- p_sys->i_atmo_width = 64;
- p_sys->i_atmo_height = 48;
- vlc_mutex_init( &p_sys->filter_lock );
- #if defined(WIN32)
- /*
- only on WIN32 the user has the choice between
- internal driver and external
- */
- b_use_buildin_driver = var_CreateGetBoolCommand( p_filter,
- CFG_PREFIX "usebuildin" );
- if(b_use_buildin_driver == false) {
- /* Load the Com Wrapper Library (source available) */
- p_sys->h_AtmoCtrl = LoadLibraryA("AtmoCtrlLib.dll");
- if(p_sys->h_AtmoCtrl != NULL)
- {
- msg_Dbg( p_filter, "LoadLibrary('AtmoCtrlLib.dll'); Success");
- /* importing all required functions I hope*/
- p_sys->pf_ctrl_atmo_initialize =
- (int32_t (*)(void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoInitialize");
- if(!p_sys->pf_ctrl_atmo_initialize)
- msg_Err( p_filter, "export AtmoInitialize missing.");
- p_sys->pf_ctrl_atmo_finalize =
- (void (*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoFinalize");
- if(!p_sys->pf_ctrl_atmo_finalize)
- msg_Err( p_filter, "export AtmoFinalize missing.");
- p_sys->pf_ctrl_atmo_switch_effect =
- (int32_t(*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSwitchEffect");
- if(!p_sys->pf_ctrl_atmo_switch_effect)
- msg_Err( p_filter, "export AtmoSwitchEffect missing.");
- p_sys->pf_ctrl_atmo_set_live_source =
- (int32_t(*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSetLiveSource");
- if(!p_sys->pf_ctrl_atmo_set_live_source)
- msg_Err( p_filter, "export AtmoSetLiveSource missing.");
- p_sys->pf_ctrl_atmo_create_transfer_buffers =
- (void (*)(int32_t, int32_t, int32_t , int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoCreateTransferBuffers");
- if(!p_sys->pf_ctrl_atmo_create_transfer_buffers)
- msg_Err( p_filter, "export AtmoCreateTransferBuffers missing.");
- p_sys->pf_ctrl_atmo_lock_transfer_buffer=
- (uint8_t*(*) (void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoLockTransferBuffer");
- if(!p_sys->pf_ctrl_atmo_lock_transfer_buffer)
- msg_Err( p_filter, "export AtmoLockTransferBuffer missing.");
- p_sys->pf_ctrl_atmo_send_pixel_data =
- (void (*)(void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSendPixelData");
- if(!p_sys->pf_ctrl_atmo_send_pixel_data)
- msg_Err( p_filter, "export AtmoSendPixelData missing.");
- } else {
- /* the DLL is missing try internal filter ...*/
- msg_Warn( p_filter, "AtmoCtrlLib.dll missing fallback to internal driver");
- b_use_buildin_driver = true;
- }
- }
- #endif
- if(b_use_buildin_driver == true) {
- msg_Dbg( p_filter, "use buildin driver");
- /*
- now we have to read a lof of options from the config dialog
- most important the serial device if not set ... we can skip
- the rest and disable the filter...
- */
- char *psz_serialdev = var_CreateGetStringCommand( p_filter,
- CFG_PREFIX "serialdev" );
- if(psz_serialdev && (strlen(psz_serialdev)>0)) {
- msg_Dbg( p_filter, "use buildin driver on port %s",psz_serialdev);
- p_sys->p_atmo_config = new CAtmoConfig();
- p_sys->p_atmo_config->setSerialDevice(psz_serialdev);
- p_sys->p_atmo_config->setLiveViewFilterMode(
- (AtmoFilterMode)var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "filtermode")
- );
- p_sys->p_atmo_config->setLiveViewFilter_PercentNew(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "PercentNew")
- );
- p_sys->p_atmo_config->setLiveViewFilter_MeanLength(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "MeanLength")
- );
- p_sys->p_atmo_config->setLiveViewFilter_MeanThreshold(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "MeanThreshold")
- );
- p_sys->p_atmo_config->setLiveView_EdgeWeighting(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "EdgeWeightning")
- );
- p_sys->p_atmo_config->setLiveView_BrightCorrect(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "Brightness")
- );
- p_sys->p_atmo_config->setLiveView_DarknessLimit(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "DarknessLimit")
- );
- p_sys->p_atmo_config->setLiveView_HueWinSize(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "HueWinSize")
- );
- p_sys->p_atmo_config->setLiveView_SatWinSize(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "SatWinSize")
- );
- /* currently not required inside vlc */
- p_sys->p_atmo_config->setLiveView_WidescreenMode( 0 );
- p_sys->p_atmo_config->setLiveView_FrameDelay(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "FrameDelay")
- );
- p_sys->p_atmo_config->setUseSoftwareWhiteAdj(
- var_CreateGetBoolCommand( p_filter, CFG_PREFIX "whiteadj")
- );
- p_sys->p_atmo_config->setWhiteAdjustment_Red(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "white-red")
- );
- p_sys->p_atmo_config->setWhiteAdjustment_Green(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "white-green")
- );
- p_sys->p_atmo_config->setWhiteAdjustment_Blue(
- var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "white-blue")
- );
- tChannelAssignment *p_channel_assignment =
- p_sys->p_atmo_config->getChannelAssignment(0);
- p_channel_assignment->mappings[0] = var_CreateGetIntegerCommand(
- p_filter, CFG_PREFIX "channel_0");
- p_channel_assignment->mappings[1] = var_CreateGetIntegerCommand(
- p_filter, CFG_PREFIX "channel_1");
- p_channel_assignment->mappings[2] = var_CreateGetIntegerCommand(
- p_filter, CFG_PREFIX "channel_2");
- p_channel_assignment->mappings[3] = var_CreateGetIntegerCommand(
- p_filter, CFG_PREFIX "channel_3");
- p_channel_assignment->mappings[4] = var_CreateGetIntegerCommand(
- p_filter, CFG_PREFIX "channel_4");
- for(int i=0;i<ATMO_NUM_CHANNELS;i++)
- msg_Dbg( p_filter, "map software channel %d to hardware channel %d",
- p_channel_assignment->mappings[i],
- i
- );
- // gradient_zone_0
- char psz_gradient_var_name[30];
- char *psz_gradient_file;
- for(int i=0;i<ATMO_NUM_CHANNELS;i++)
- {
- sprintf(psz_gradient_var_name, CFG_PREFIX "gradient_zone_%d", i);
- psz_gradient_file = var_CreateGetStringCommand(
- p_filter,
- psz_gradient_var_name
- );
- if(psz_gradient_file && strlen(psz_gradient_file)>0)
- {
- msg_Dbg( p_filter, "loading gradientfile %s for "
- "zone %d", psz_gradient_file, i);
- int i_res = p_sys->p_atmo_config->getZoneDefinition(i)->
- LoadGradientFromBitmap(psz_gradient_file);
- if(i_res != ATMO_LOAD_GRADIENT_OK)
- {
- msg_Err( p_filter,"failed to load gradient '%s' with "
- "error %d",psz_gradient_file,i_res);
- }
- }
- free( psz_gradient_file );
- }
- p_sys->p_atmo_dyndata = new CAtmoDynData((vlc_object_t *)p_filter,
- p_sys->p_atmo_config
- );
- msg_Dbg( p_filter, "buildin driver initialized");
- free(psz_serialdev);
- } else {
- msg_Err(p_filter,"no serial devicename set");
- }
- }
- switch( p_filter->fmt_in.video.i_chroma )
- {
- case VLC_FOURCC('I','4','2','0'):
- case VLC_FOURCC('I','Y','U','V'):
- case VLC_FOURCC('Y','V','1','2'):
- case VLC_FOURCC('Y','V','1','6'):
- case VLC_FOURCC('Y','V','U','9'):
- // simple enough? Dionoea?
- p_sys->pf_extract_mini_image = ExtractMiniImage_YUV;
- break;
- default:
- msg_Dbg( p_filter, "InitFilter-unsupported chroma: %4.4s",
- (char *)&p_filter->fmt_in.video.i_chroma);
- p_sys->pf_extract_mini_image = NULL;
- }
- p_sys->i_crop_x_offset = 0;
- p_sys->i_crop_y_offset = 0;
- p_sys->i_crop_width = p_filter->fmt_in.video.i_visible_width;
- p_sys->i_crop_height = p_filter->fmt_in.video.i_visible_height;
- msg_Dbg( p_filter, "set default crop %d,%d %dx%d",p_sys->i_crop_x_offset,
- p_sys->i_crop_y_offset,
- p_sys->i_crop_width,
- p_sys->i_crop_height );
- #if defined(__ATMO_DEBUG__)
- /* save debug images to a folder as Bitmap files ? */
- p_sys->b_saveframes = var_CreateGetBoolCommand( p_filter,
- CFG_PREFIX "saveframes"
- );
- msg_Dbg(p_filter,"saveframes = %d", (int)p_sys->b_saveframes);
- /*
- read debug image folder from config
- */
- psz_path = var_CreateGetStringCommand( p_filter, CFG_PREFIX "framepath" );
- if(psz_path != NULL)
- {
- strcpy(p_sys->sz_framepath, psz_path);
- #if defined( WIN32 )
- size_t i_strlen = strlen(p_sys->sz_framepath);
- if((i_strlen>0) && (p_sys->sz_framepath[i_strlen-1] != '\'))
- {
- p_sys->sz_framepath[i_strlen] = '\';
- p_sys->sz_framepath[i_strlen+1] = 0;
- }
- #endif
- free(psz_path);
- }
- msg_Dbg(p_filter,"saveframesfolder %s",p_sys->sz_framepath);
- #endif
- /*
- size of extracted image by default 64x48 (other imagesizes are
- currently ignored by AtmoWin)
- */
- p_sys->i_atmo_width = var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "width");
- p_sys->i_atmo_height = var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "height");
- msg_Dbg(p_filter,"mini image size %d * %d pixels", p_sys->i_atmo_width,
- p_sys->i_atmo_height);
- /*
- because atmowin could also be used for lighten up the room - I think if you
- pause the video it would be useful to get a little bit more light into to
- your living room? - instead switching on a lamp?
- */
- p_sys->b_usepausecolor = var_CreateGetBoolCommand( p_filter,
- CFG_PREFIX "usepausecolor" );
- p_sys->ui_pausecolor_red = (uint8_t)var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "pcolor-red");
- p_sys->ui_pausecolor_green = (uint8_t)var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "pcolor-green");
- p_sys->ui_pausecolor_blue = (uint8_t)var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "pcolor-blue");
- p_sys->i_fadesteps = var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "fadesteps");
- if(p_sys->i_fadesteps < 1)
- p_sys->i_fadesteps = 1;
- msg_Dbg(p_filter,"use pause color %d, RGB: %d, %d, %d, Fadesteps: %d",
- (int)p_sys->b_usepausecolor,
- p_sys->ui_pausecolor_red,
- p_sys->ui_pausecolor_green,
- p_sys->ui_pausecolor_blue,
- p_sys->i_fadesteps);
- /*
- this color is use on shutdown of the filter - the define the
- final light after playback... may be used to dim up the light -
- how it happens in the cinema...
- */
- p_sys->ui_endcolor_red = (uint8_t)var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "ecolor-red");
- p_sys->ui_endcolor_green = (uint8_t)var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "ecolor-green");
- p_sys->ui_endcolor_blue = (uint8_t)var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "ecolor-blue");
- p_sys->i_endfadesteps = var_CreateGetIntegerCommand( p_filter,
- CFG_PREFIX "efadesteps");
- if(p_sys->i_endfadesteps < 1)
- p_sys->i_endfadesteps = 1;
- msg_Dbg(p_filter,"use ende color RGB: %d, %d, %d, Fadesteps: %d",
- p_sys->ui_endcolor_red,
- p_sys->ui_endcolor_green,
- p_sys->ui_endcolor_blue,
- p_sys->i_endfadesteps);
- /* if the external DLL was loaded successfully call AtmoInitialize -
- (must be done for each thread where you wan't to use AtmoLight!
- */
- int i = AtmoInitialize(p_filter, false);
- #if defined( WIN32 )
- if((i != 1) && !b_use_buildin_driver)
- {
- /* COM Server for AtmoLight not running ?
- if the exe path is configured try to start the "userspace" driver
- */
- psz_path = var_CreateGetStringCommand( p_filter,
- CFG_PREFIX "atmowinexe" );
- if(psz_path != NULL)
- {
- STARTUPINFO startupinfo;
- PROCESS_INFORMATION pinfo;
- memset(&startupinfo, 0, sizeof(STARTUPINFO));
- startupinfo.cb = sizeof(STARTUPINFO);
- if(CreateProcess(psz_path, NULL, NULL, NULL,
- FALSE, 0, NULL, NULL, &startupinfo, &pinfo) == TRUE)
- {
- msg_Dbg(p_filter,"launched AtmoWin from %s",psz_path);
- WaitForInputIdle(pinfo.hProcess, 5000);
- /*
- retry to initialize the library COM ... functionality
- after the server was launched
- */
- i = AtmoInitialize(p_filter, false);
- } else {
- msg_Err(p_filter,"failed to launch AtmoWin from %s", psz_path);
- }
- free(psz_path);
- }
- }
- #endif
- if(i == 1) /* Init Atmolight success... */
- {
- msg_Dbg( p_filter, "AtmoInitialize Ok!");
- /* Setup Transferbuffers for 64 x 48 , RGB with 32bit Per Pixel */
- AtmoCreateTransferBuffers(p_filter, BI_RGB, 4,
- p_sys->i_atmo_width,
- p_sys->i_atmo_height
- );
- /* say the userspace driver that a live mode should be activated
- the functions returns the old mode for later restore!
- */
- p_sys->i_AtmoOldEffect = AtmoSwitchEffect(p_filter, emLivePicture);
- /*
- live view can have two differnt source the AtmoWinA
- internal GDI Screencapture and the external one - which we
- need here...
- */
- AtmoSetLiveSource(p_filter, lvsExternal);
- /* enable other parts only if everything is fine */
- p_sys->b_enabled = true;
- }
- }
- /*****************************************************************************
- * CreateFilter: allocates AtmoLight video thread output method
- *****************************************************************************
- * This function allocates and initializes a AtmoLight vout method.
- *****************************************************************************/
- static int CreateFilter( vlc_object_t *p_this )
- {
- filter_t *p_filter = (filter_t *)p_this;
- filter_sys_t *p_sys;
- /* Allocate structure */
- p_sys = (filter_sys_t *)malloc( sizeof( filter_sys_t ) );
- p_filter->p_sys = p_sys;
- if( p_filter->p_sys == NULL )
- return VLC_ENOMEM;
- /* set all entries to zero */
- memset(p_sys, 0, sizeof( filter_sys_t ));
- /* further Setup Function pointers for videolan for calling my filter */
- p_filter->pf_video_filter = Filter;
- config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
- p_filter->p_cfg );
- AddStateVariableCallback(p_filter);
- AddCropVariableCallback(p_filter);
- AddAtmoSettingsVariablesCallbacks(p_filter);
- Atmo_SetupParameters(p_filter);
- return VLC_SUCCESS;
- }
- /*****************************************************************************
- * DestroyFilter: destroy AtmoLight video thread output method
- *****************************************************************************
- * Terminate an output method created by CreateFilter
- *****************************************************************************/
- static void DestroyFilter( vlc_object_t *p_this )
- {
- filter_t *p_filter = (filter_t *)p_this;
- filter_sys_t *p_sys = p_filter->p_sys;
- DelStateVariableCallback(p_filter);
- DelCropVariableCallback(p_filter);
- DelAtmoSettingsVariablesCallbacks(p_filter);
- Atmo_Shutdown(p_filter);
- #if defined( WIN32 )
- if(p_sys->h_AtmoCtrl != NULL)
- {
- FreeLibrary(p_sys->h_AtmoCtrl);
- }
- #endif
- delete p_sys->p_atmo_dyndata;
- delete p_sys->p_atmo_config;
- vlc_mutex_destroy( &p_sys->filter_lock );
- free( p_sys );
- }
- /*
- function stolen from some other videolan source filter ;-)
- for the moment RGB is OK... but better would be a direct transformation
- from YUV --> HSV
- */
- static inline void yuv_to_rgb( uint8_t *r, uint8_t *g, uint8_t *b,
- uint8_t y1, uint8_t u1, uint8_t v1 )
- {
- /* macros used for YUV pixel conversions */
- # define SCALEBITS 10
- # define ONE_HALF (1 << (SCALEBITS - 1))
- # define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
- # define CLAMP( x ) (((x) > 255) ? 255 : ((x) < 0) ? 0 : (x));
- int y, cb, cr, r_add, g_add, b_add;
- cb = u1 - 128;
- cr = v1 - 128;
- r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;
- g_add = - FIX(0.34414*255.0/224.0) * cb
- - FIX(0.71414*255.0/224.0) * cr + ONE_HALF;
- b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;
- y = (y1 - 16) * FIX(255.0/219.0);
- *r = CLAMP((y + r_add) >> SCALEBITS);
- *g = CLAMP((y + g_add) >> SCALEBITS);
- *b = CLAMP((y + b_add) >> SCALEBITS);
- }
- /******************************************************************************
- * ExtractMiniImage_YUV: extract a small image from the picture as 24-bit RGB
- *******************************************************************************
- * p_sys is a pointer to
- * p_inpic is the source frame
- * p_transfer_dest is the target buffer for the picture must be big enough!
- * (in win32 enviroment this buffer comes from the external DLL where it is
- * create as "variant array" and returned through the AtmoLockTransferbuffer
- */
- static void ExtractMiniImage_YUV(filter_sys_t *p_sys,
- picture_t *p_inpic,
- uint8_t *p_transfer_dest)
- {
- int i_col;
- int i_row;
- uint8_t *p_src_y;
- uint8_t *p_src_u;
- uint8_t *p_src_v;
- uint8_t *p_rgb_dst_line_red;
- uint8_t *p_rgb_dst_line_green;
- uint8_t *p_rgb_dst_line_blue;
- int i_xpos_y;
- int i_xpos_u;
- int i_xpos_v;
- /* calcute Pointers for Storage of B G R (A) */
- p_rgb_dst_line_blue = p_transfer_dest;
- p_rgb_dst_line_green = p_transfer_dest + 1;
- p_rgb_dst_line_red = p_transfer_dest + 2 ;
- int i_row_count = p_sys->i_atmo_height + 1;
- int i_col_count = p_sys->i_atmo_width + 1;
- int i_y_row,i_u_row,i_v_row,i_pixel_row;
- int i_pixel_col;
- /* these two ugly loops extract the small image - goes it faster? how?
- the loops are so designed that there is a small border around the extracted
- image so we wont get column and row - zero from the frame, and not the most
- right and bottom pixels --- which may be clipped on computers useing TV out
- - through overscan!
- TODO: try to find out if the output is clipped through VLC - and try here
- to ingore the clipped away area for a better result!
- TODO: performance improvement in InitFilter percalculated the offsets of
- the lines inside the planes so I can save (i_row_count * 3) 2xMUL and
- one time DIV the same could be done for the inner loop I think...
- */
- for(i_row = 1; i_row < i_row_count; i_row++)
- {
- // calcute the current Lines in the source planes for this outputrow
- /* Adresscalcuation pointer to plane Length of one pixelrow in bytes
- calculate row now number
- */
- /*
- p_inpic->format? transform Pixel row into row of plane...
- how? simple? fast? good?
- */
- /* compute the source pixel row and respect the active cropping */
- i_pixel_row = (i_row * p_sys->i_crop_height) / i_row_count
- + p_sys->i_crop_y_offset;
- /*
- trans for these Pixel row into the row of each plane ..
- because planesize can differ from image size
- */
- i_y_row = (i_pixel_row * p_inpic->p[Y_PLANE].i_visible_lines) /
- p_inpic->format.i_visible_height;
- i_u_row = (i_pixel_row * p_inpic->p[U_PLANE].i_visible_lines) /
- p_inpic->format.i_visible_height;
- i_v_row = (i_pixel_row * p_inpic->p[V_PLANE].i_visible_lines) /
- p_inpic->format.i_visible_height;
- /* calculate the pointers to the pixeldata for this row
- in each plane
- */
- p_src_y = p_inpic->p[Y_PLANE].p_pixels +
- p_inpic->p[Y_PLANE].i_pitch * i_y_row;
- p_src_u = p_inpic->p[U_PLANE].p_pixels +
- p_inpic->p[U_PLANE].i_pitch * i_u_row;
- p_src_v = p_inpic->p[V_PLANE].p_pixels +
- p_inpic->p[V_PLANE].i_pitch * i_v_row;
- for(i_col = 1; i_col < i_col_count; i_col++)
- {
- i_pixel_col = (i_col * p_sys->i_crop_width) / i_col_count +
- p_sys->i_crop_x_offset;
- /*
- trans for these Pixel row into the row of each plane ..
- because planesize can differ from image size
- */
- i_xpos_y = (i_pixel_col * p_inpic->p[Y_PLANE].i_visible_pitch) /
- p_inpic->format.i_visible_width;
- i_xpos_u = (i_pixel_col * p_inpic->p[U_PLANE].i_visible_pitch) /
- p_inpic->format.i_visible_width;
- i_xpos_v = (i_pixel_col * p_inpic->p[V_PLANE].i_visible_pitch) /
- p_inpic->format.i_visible_width;
- yuv_to_rgb(p_rgb_dst_line_red,
- p_rgb_dst_line_green,
- p_rgb_dst_line_blue,
- p_src_y[i_xpos_y],
- p_src_u[i_xpos_u],
- p_src_v[i_xpos_v]);
- /* +4 because output image should be RGB32 with dword alignment! */
- p_rgb_dst_line_red += 4;
- p_rgb_dst_line_green += 4;
- p_rgb_dst_line_blue += 4;
- }
- }
- }
- /******************************************************************************
- * SaveBitmap: Saves the content of a transferbuffer as Bitmap to disk
- *******************************************************************************
- * just for debugging
- * p_sys -> configuration if Atmo from there the function will get height and
- * width
- * p_pixels -> should be the dword aligned BGR(A) image data
- * psz_filename -> filename where to store
- */
- #if defined(__ATMO_DEBUG__)
- void SaveBitmap(filter_sys_t *p_sys, uint8_t *p_pixels, char *psz_filename)
- {
- /* for debug out only used*/
- BITMAPINFO bmp_info;
- BITMAPFILEHEADER bmp_fileheader;
- FILE *fp_bitmap;
- memset(&bmp_info, 0, sizeof(BITMAPINFO));
- bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmp_info.bmiHeader.biSizeImage = p_sys->i_atmo_height *
- p_sys->i_atmo_width * 4;
- bmp_info.bmiHeader.biCompression = BI_RGB;
- bmp_info.bmiHeader.biWidth = p_sys->i_atmo_width;
- bmp_info.bmiHeader.biHeight = -p_sys->i_atmo_height;
- bmp_info.bmiHeader.biBitCount = 32;
- bmp_info.bmiHeader.biPlanes = 1;
- bmp_fileheader.bfReserved1 = 0;
- bmp_fileheader.bfReserved2 = 0;
- bmp_fileheader.bfSize = sizeof(BITMAPFILEHEADER) +
- sizeof(BITMAPINFOHEADER) +
- bmp_info.bmiHeader.biSizeImage;
- bmp_fileheader.bfType = VLC_TWOCC('M','B');
- bmp_fileheader.bfOffBits = sizeof(BITMAPFILEHEADER) +
- sizeof(BITMAPINFOHEADER);
- fp_bitmap = fopen(psz_filename,"wb");
- if( fp_bitmap != NULL)
- {
- fwrite(&bmp_fileheader, sizeof(BITMAPFILEHEADER), 1, fp_bitmap);
- fwrite(&bmp_info.bmiHeader, sizeof(BITMAPINFOHEADER), 1, fp_bitmap);
- fwrite(p_pixels, bmp_info.bmiHeader.biSizeImage, 1, fp_bitmap);
- fclose(fp_bitmap);
- }
- }
- #endif
- /****************************************************************************
- * CreateMiniImage: extracts a 64x48 pixel image from the frame
- * (there is a small border arround thats why the loops starts with one
- * instead zero) without any interpolation
- *****************************************************************************/
- static void CreateMiniImage( filter_t *p_filter, picture_t *p_inpic)
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- /*
- pointer to RGB Buffer created in external libary as safe array which
- is locked inside AtmoLockTransferBuffer
- */
- uint8_t *p_transfer = NULL;
- #if defined( __ATMO_DEBUG__ )
- /* for debug out only used*/
- char sz_filename[MAX_PATH];
- #endif
- /*
- Lock the before created VarArray (AtmoCreateTransferBuffers)
- inside my wrapper library and give me a pointer to the buffer!
- below linux a global buffer may be used and protected with a mutex?
- */
- p_transfer = AtmoLockTransferBuffer(p_filter);
- if(p_transfer == NULL)
- {
- msg_Err( p_filter, "AtmoLight no transferbuffer available. "
- "AtmoLight will be disabled!");
- p_sys->b_enabled = false;
- return;
- }
- /*
- do the call via pointer to function instead of having a
- case structure here
- */
- p_sys->pf_extract_mini_image(p_sys, p_inpic, p_transfer);
- #if defined( __ATMO_DEBUG__ )
- /*
- if debugging enabled save every 128th image to disk
- */
- if((p_sys->b_saveframes == true) && (p_sys->sz_framepath[0] != 0 ))
- {
- if((p_sys->i_framecounter & 127) == 0)
- {
- sprintf(sz_filename,"%satmo_dbg_%06d.bmp",p_sys->sz_framepath,
- p_sys->i_framecounter);
- msg_Dbg(p_filter, "SaveFrame %s",sz_filename);
- SaveBitmap(p_sys, p_transfer, sz_filename);
- }
- p_sys->i_framecounter++;
- }
- #endif
- /* show the colors on the wall */
- AtmoSendPixelData(p_filter);
- }
- /*****************************************************************************
- * Filter: calls the extract method and forwards the incomming picture 1:1
- *****************************************************************************
- *
- *****************************************************************************/
- static picture_t * Filter( filter_t *p_filter, picture_t *p_pic )
- {
- filter_sys_t *p_sys = p_filter->p_sys;
- if( !p_pic ) return NULL;
- if((p_sys->b_enabled == true) &&
- (p_sys->pf_extract_mini_image != NULL) &&
- (p_sys->b_pause_live == false))
- {
- CreateMiniImage(p_filter, p_pic);
- }
- return p_pic;
- }
- /*****************************************************************************
- * FadeToColorThread: Threadmethod which changes slowly the color
- * to a target color defined in p_fadethread struct
- * use for: Fade to Pause Color, and Fade to End Color
- *****************************************************************************/
- static void *FadeToColorThread(vlc_object_t *obj)
- {
- fadethread_t *p_fadethread = (fadethread_t *)obj;
- filter_sys_t *p_sys = (filter_sys_t *)p_fadethread->p_filter->p_sys;
- int i_steps_done = 0;
- int i_index;
- int i_pause_red;
- int i_pause_green;
- int i_pause_blue;
- int i_src_red;
- int i_src_green;
- int i_src_blue;
- uint8_t *p_source = NULL;
- int canc = vlc_savecancel ();
- /* initialize AtmoWin for this thread! */
- AtmoInitialize(p_fadethread->p_filter , true);
- uint8_t *p_transfer = AtmoLockTransferBuffer( p_fadethread->p_filter );
- if(p_transfer != NULL) {
- /* safe colors as "32bit" Integers to avoid overflows*/
- i_pause_red = p_fadethread->ui_red;
- i_pause_blue = p_fadethread->ui_blue;
- i_pause_green = p_fadethread->ui_green;
- /*
- allocate a temporary buffer for the last send
- image size less then 15kb
- */
- int i_size = 4 * p_sys->i_atmo_width * p_sys->i_atmo_height;
- p_source = (uint8_t *)malloc( i_size );
- if(p_source != NULL)
- {
- /*
- get a copy of the last transfered image as orign for the
- fading steps...
- */
- memcpy(p_source, p_transfer, i_size);
- /* send the same pixel data again... to unlock the buffer! */
- AtmoSendPixelData( p_fadethread->p_filter );
- while( (vlc_object_alive (p_fadethread)) &&
- (i_steps_done < p_fadethread->i_steps))
- {
- p_transfer = AtmoLockTransferBuffer( p_fadethread->p_filter );
- if(!p_transfer) break; /* should not happen if it worked
- one time in the code above! */
- i_steps_done++;
- /*
- move all pixels in the mini image (64x48) one step closer to
- the desired color these loop takes the most time of this
- thread improvements wellcome!
- */
- for(i_index = 0;
- (i_index < i_size) && (vlc_object_alive (p_fadethread));
- i_index+=4)
- {
- i_src_blue = p_source[i_index+0];
- i_src_green = p_source[i_index+1];
- i_src_red = p_source[i_index+2];
- p_transfer[i_index+0] = (uint8_t) (((
- (i_pause_blue - i_src_blue)
- * i_steps_done)/p_fadethread->i_steps)
- + i_src_blue);
- p_transfer[i_index+1] = (uint8_t) (((
- (i_pause_green - i_src_green)
- * i_steps_done)/p_fadethread->i_steps)
- + i_src_green);
- p_transfer[i_index+2] = (uint8_t) (((
- (i_pause_red - i_src_red)
- * i_steps_done)/p_fadethread->i_steps)
- + i_src_red);
- }
- /* send image to lightcontroller */
- AtmoSendPixelData( p_fadethread->p_filter );
- /* is there something like and interruptable sleep inside
- the VLC libaries? inside native win32 I would use an Event
- (CreateEvent) and here an WaitForSingleObject?
- */
- if(!vlc_object_alive (p_fadethread)) break;
- msleep(10000);
- if(!vlc_object_alive (p_fadethread)) break;
- msleep(10000);
- if(!vlc_object_alive (p_fadethread)) break;
- msleep(10000);
- if(!vlc_object_alive (p_fadethread)) break;
- msleep(10000);
- }
- free(p_source);
- } else {
- /* in failure of malloc also unlock buffer */
- AtmoSendPixelData(p_fadethread->p_filter);
- }
- }
- /* call indirect to OleUnitialize() for this thread */
- AtmoFinalize(p_fadethread->p_filter, 0);
- vlc_restorecancel (canc);
- return NULL;
- }
- /*****************************************************************************
- * CheckAndStopFadeThread: if there is a fadethread structure left, or running.
- ******************************************************************************
- * this function will stop the thread ... and waits for its termination
- * before removeing the objects from vout_sys_t ...
- ******************************************************************************/
- static void CheckAndStopFadeThread(filter_t *p_filter)
- {
- filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
- vlc_mutex_lock( &p_sys->filter_lock );
- if(p_sys->p_fadethread != NULL)
- {
- msg_Dbg(p_filter, "kill still running fadeing thread...");
- p_sys->p_fadethread->b_die = true;
- vlc_thread_join(p_sys->p_fadethread);
- vlc_object_release(p_sys->p_fadethread);
- p_sys->p_fadethread = NULL;
- }
- vlc_mutex_unlock( &p_sys->filter_lock );
- }
- /*****************************************************************************
- * StateCallback: Callback for the inputs variable "State" to get notified
- * about Pause and Continue Playback events.
- *****************************************************************************/
- static int StateCallback( vlc_object_t *p_this, char const *psz_cmd,
- vlc_value_t oldval, vlc_value_t newval,
- void *p_data )
- {
- filter_t *p_filter = (filter_t *)p_data;
- filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
- if((p_sys->b_usepausecolor == true) && (p_sys->b_enabled == true))
- {
- msg_Dbg(p_filter, "state change from: %d to %d", oldval.i_int,
- newval.i_int);
- if((newval.i_int == PAUSE_S) && (oldval.i_int == PLAYING_S))
- {
- /* tell the other thread to stop sending images to light
- controller */
- p_sys->b_pause_live = true;
- // ggf. alten Thread abräumen should not happen....
- CheckAndStopFadeThread(p_filter);
- // perpare spawn fadeing thread
- vlc_mutex_lock( &p_sys->filter_lock );
- /*
- launch only a new thread if there is none active!
- or waiting for cleanup
- */
- if(p_sys->p_fadethread == NULL)
- {
- p_sys->p_fadethread = (fadethread_t *)vlc_object_create(
- p_filter,
- sizeof(fadethread_t) );
- p_sys->p_fadethread->p_filter = p_filter;
- p_sys->p_fadethread->ui_red = p_sys->ui_pausecolor_red;
- p_sys->p_fadethread->ui_green = p_sys->ui_pausecolor_green;
- p_sys->p_fadethread->ui_blue = p_sys->ui_pausecolor_blue;
- p_sys->p_fadethread->i_steps = p_sys->i_fadesteps;
- if( vlc_thread_create( p_sys->p_fadethread,
- "AtmoLight fadeing",
- FadeToColorThread,
- VLC_THREAD_PRIORITY_LOW ) )
- {
- msg_Err( p_filter, "cannot create FadeToColorThread" );
- vlc_object_release( p_sys->p_fadethread );
- p_sys->p_fadethread = NULL;
- }
- }
- vlc_mutex_unlock( &p_sys->filter_lock );
- }
- if((newval.i_int == PLAYING_S) && (oldval.i_int == PAUSE_S))
- {
- /* playback continues check thread state */
- CheckAndStopFadeThread(p_filter);
- /* reactivate the Render function... to do its normal work */
- p_sys->b_pause_live = false;
- }
- }
- return VLC_SUCCESS;
- }
- /*****************************************************************************
- * AddPlaylistInputThreadStateCallback: Setup call back on "State" Variable
- *****************************************************************************
- * Add Callback function to the "state" variable of the input thread..
- * first find the PlayList and get the input thread from there to attach
- * my callback? is vlc_object_find the right way for this??
- *****************************************************************************/
- static void AddStateVariableCallback(filter_t *p_filter)
- {
- playlist_t *p_playlist = pl_Hold( p_filter );
- input_thread_t *p_input = playlist_CurrentInput( p_playlist );
- if(p_input)
- {
- var_AddCallback( p_input, "state", StateCallback, p_filter );
- vlc_object_release( p_input );
- }
- pl_Release( p_filter );
- }
- /*****************************************************************************
- * DelPlaylistInputThreadStateCallback: Remove call back on "State" Variable
- *****************************************************************************
- * Delete the callback function to the "state" variable of the input thread...
- * first find the PlayList and get the input thread from there to attach
- * my callback? is vlc_object_find the right way for this??
- *****************************************************************************/
- static void DelStateVariableCallback( filter_t *p_filter )
- {
- playlist_t *p_playlist = pl_Hold( p_filter );
- input_thread_t *p_input = playlist_CurrentInput( p_playlist );
- if(p_input)
- {
- var_DelCallback( p_input, "state", StateCallback, p_filter );
- vlc_object_release( p_input );
- }
- pl_Release( p_filter );
- }
- static int CropCallback(vlc_object_t *p_this, char const *psz_cmd,
- vlc_value_t oldval, vlc_value_t newval,
- void *p_data)
- {
- vout_thread_t *p_vout = (vout_thread_t *)p_this;
- filter_t *p_filter = (filter_t *)p_data;
- filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
- /*
- //if the handler is attache to crop variable directly!
- int i_visible_width, i_visible_height, i_x_offset, i_y_offset;
- atmo_parse_crop(newval.psz_string, p_vout->fmt_render,
- p_vout->fmt_render,
- i_visible_width, i_visible_height,
- i_x_offset, i_y_offset);
- p_sys->i_crop_x_offset = i_x_offset;
- p_sys->i_crop_y_offset = i_y_offset;
- p_sys->i_crop_width = i_visible_width;
- p_sys->i_crop_height = i_visible_height;
- */
- p_sys->i_crop_x_offset = p_vout->fmt_in.i_x_offset;
- p_sys->i_crop_y_offset = p_vout->fmt_in.i_y_offset;
- p_sys->i_crop_width = p_vout->fmt_in.i_visible_width;
- p_sys->i_crop_height = p_vout->fmt_in.i_visible_height;
- msg_Dbg(p_filter, "cropping picture %ix%i to %i,%i,%ix%i",
- p_vout->fmt_in.i_width,
- p_vout->fmt_in.i_height,
- p_sys->i_crop_x_offset,
- p_sys->i_crop_y_offset,
- p_sys->i_crop_width,
- p_sys->i_crop_height
- );
- return VLC_SUCCESS;
- }
- static void AddCropVariableCallback( filter_t *p_filter)
- {
- vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find( p_filter,
- VLC_OBJECT_VOUT,
- FIND_ANYWHERE );
- if( p_vout )
- {
- var_AddCallback( p_vout, "crop-update", CropCallback, p_filter );
- vlc_object_release( p_vout );
- }
- }
- static void DelCropVariableCallback( filter_t *p_filter)
- {
- vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find( p_filter,
- VLC_OBJECT_VOUT,
- FIND_ANYWHERE );
- if( p_vout )
- {
- var_DelCallback( p_vout, "crop-update", CropCallback, p_filter );
- vlc_object_release( p_vout );
- }
- }
- /****************************************************************************
- * StateCallback: Callback for the inputs variable "State" to get notified
- * about Pause and Continue Playback events.
- *****************************************************************************/
- static int AtmoSettingsCallback( vlc_object_t *p_this, char const *psz_var,
- vlc_value_t oldval, vlc_value_t newval,
- void *p_data )
- {
- filter_t *p_filter = (filter_t *)p_data;
- filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
- CAtmoConfig *p_atmo_config = p_sys->p_atmo_config;
- if(p_atmo_config)
- {
- msg_Dbg(p_filter, "apply AtmoSettingsCallback %s (int: %d -> %d)",
- psz_var,
- oldval.i_int,
- newval.i_int
- );
- if( !strcmp( psz_var, CFG_PREFIX "filtermode" ))
- p_atmo_config->setLiveViewFilterMode( (AtmoFilterMode)newval.i_int);
- else if( !strcmp( psz_var, CFG_PREFIX "PercentNew" ))
- p_atmo_config->setLiveViewFilter_PercentNew( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "MeanLength" ))
- p_atmo_config->setLiveViewFilter_MeanLength( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "MeanThreshold" ))
- p_atmo_config->setLiveViewFilter_MeanThreshold( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "EdgeWeightning" ))
- p_atmo_config->setLiveView_EdgeWeighting( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "Brightness" ))
- p_atmo_config->setLiveView_BrightCorrect( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "DarknessLimit" ))
- p_atmo_config->setLiveView_DarknessLimit( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "HueWinSize" ))
- p_atmo_config->setLiveView_HueWinSize( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "SatWinSize" ))
- p_atmo_config->setLiveView_SatWinSize( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "FrameDelay" ))
- p_atmo_config->setLiveView_FrameDelay( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "whiteadj" ))
- p_atmo_config->setUseSoftwareWhiteAdj( newval.b_bool );
- else if( !strcmp( psz_var, CFG_PREFIX "white-red" ))
- p_atmo_config->setWhiteAdjustment_Red( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "white-green" ))
- p_atmo_config->setWhiteAdjustment_Green( newval.i_int );
- else if( !strcmp( psz_var, CFG_PREFIX "white-blue" ))
- p_atmo_config->setWhiteAdjustment_Blue( newval.i_int );
- }
- return VLC_SUCCESS;
- }
- static void AddAtmoSettingsVariablesCallbacks(filter_t *p_filter)
- {
- var_AddCallback( p_filter, CFG_PREFIX "filtermode",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "PercentNew",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "MeanLength",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "MeanThreshold",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "EdgeWeightning",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "Brightness",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "DarknessLimit",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "HueWinSize",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "SatWinSize",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "FrameDelay",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "whiteadj",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "white-red",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "white-green",
- AtmoSettingsCallback, p_filter );
- var_AddCallback( p_filter, CFG_PREFIX "white-blue",
- AtmoSettingsCallback, p_filter );
- }
- static void DelAtmoSettingsVariablesCallbacks( filter_t *p_filter )
- {
- var_DelCallback( p_filter, CFG_PREFIX "filtermode",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "PercentNew",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "MeanLength",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "MeanThreshold",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "EdgeWeightning",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "Brightness",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "DarknessLimit",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "HueWinSize",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "SatWinSize",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "FrameDelay",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "whiteadj",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "white-red",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "white-green",
- AtmoSettingsCallback, p_filter );
- var_DelCallback( p_filter, CFG_PREFIX "white-blue",
- AtmoSettingsCallback, p_filter );
- }
- #if defined(__ATMO_DEBUG__)
- static void atmo_parse_crop(char *psz_cropconfig,
- video_format_t fmt_in,
- video_format_t fmt_render,
- int &i_visible_width, int &i_visible_height,
- int &i_x_offset, int &i_y_offset )
- {
- int64_t i_aspect_num, i_aspect_den;
- unsigned int i_width, i_height;
- i_visible_width = fmt_in.i_visible_width;
- i_visible_height = fmt_in.i_visible_height;
- i_x_offset = fmt_in.i_x_offset;
- i_y_offset = fmt_in.i_y_offset;
- char *psz_end = NULL, *psz_parser = strchr( psz_cropconfig, ':' );
- if( psz_parser )
- {
- /* We're using the 3:4 syntax */
- i_aspect_num = strtol( psz_cropconfig, &psz_end, 10 );
- if( psz_end == psz_cropconfig || !i_aspect_num ) return;
- i_aspect_den = strtol( ++psz_parser, &psz_end, 10 );
- if( psz_end == psz_parser || !i_aspect_den ) return;
- i_width = fmt_in.i_sar_den * fmt_render.i_visible_height *
- i_aspect_num / i_aspect_den / fmt_in.i_sar_num;
- i_height = fmt_render.i_visible_width*fmt_in.i_sar_num *
- i_aspect_den / i_aspect_num / fmt_in.i_sar_den;
- if( i_width < fmt_render.i_visible_width )
- {
- i_x_offset = fmt_render.i_x_offset +
- (fmt_render.i_visible_width - i_width) / 2;
- i_visible_width = i_width;
- }
- else
- {
- i_y_offset = fmt_render.i_y_offset +
- (fmt_render.i_visible_height - i_height) / 2;
- i_visible_height = i_height;
- }
- }
- else
- {
- psz_parser = strchr( psz_cropconfig, 'x' );
- if( psz_parser )
- {
- /* Maybe we're using the <width>x<height>+<left>+<top> syntax */
- unsigned int i_crop_width, i_crop_height, i_crop_top, i_crop_left;
- i_crop_width = strtol( psz_cropconfig, &psz_end, 10 );
- if( psz_end != psz_parser ) return;
- psz_parser = strchr( ++psz_end, '+' );
- i_crop_height = strtol( psz_end, &psz_end, 10 );
- if( psz_end != psz_parser ) return;
- psz_parser = strchr( ++psz_end, '+' );
- i_crop_left = strtol( psz_end, &psz_end, 10 );
- if( psz_end != psz_parser ) return;
- psz_end++;
- i_crop_top = strtol( psz_end, &psz_end, 10 );
- if( *psz_end != ' ' ) return;
- i_width = i_crop_width;
- i_visible_width = i_width;
- i_height = i_crop_height;
- i_visible_height = i_height;
- i_x_offset = i_crop_left;
- i_y_offset = i_crop_top;
- }
- else
- {
- /* Maybe we're using the <left>+<top>+<right>+<bottom> syntax */
- unsigned int i_crop_top, i_crop_left, i_crop_bottom, i_crop_right;
- psz_parser = strchr( psz_cropconfig, '+' );
- i_crop_left = strtol( psz_cropconfig, &psz_end, 10 );
- if( psz_end != psz_parser ) return;
- psz_parser = strchr( ++psz_end, '+' );
- i_crop_top = strtol( psz_end, &psz_end, 10 );
- if( psz_end != psz_parser ) return;
- psz_parser = strchr( ++psz_end, '+' );
- i_crop_right = strtol( psz_end, &psz_end, 10 );
- if( psz_end != psz_parser ) return;
- psz_end++;
- i_crop_bottom = strtol( psz_end, &psz_end, 10 );
- if( *psz_end != ' ' ) return;
- i_width = fmt_render.i_visible_width - i_crop_left - i_crop_right;
- i_visible_width = i_width;
- i_height = fmt_render.i_visible_height - i_crop_top - i_crop_bottom;
- i_visible_height = i_height;
- i_x_offset = i_crop_left;
- i_y_offset = i_crop_top;
- }
- }
- }
- #endif