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); }
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_time1; 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_time1 - 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_time1 - frameDelay, (i_frame_counter == 0), m_pLog, packet_time); #else ColorPacket = pPacketQueue->GetNextPacket(get_time1 - 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 (char *)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_time1; 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_time1; if(ColorPacket) { /* pass it through the outputfilters! */ // Info Filtering will possible free the colorpacket and alloc a new one! ColorPacket = filter->Filtering(ColorPacket); // invert colors if(pAtmoConfig->isUseinvert()) ColorPacket = CAtmoTools::Applyinvert(pAtmoConfig, ColorPacket); /* apply gamma correction - only if the hardware isnt capable doing this */ ColorPacket = CAtmoTools::ApplyGamma(pAtmoConfig, ColorPacket); // load color correction from Kodak 3D-Lut file if(pAtmoConfig->isUse3dlut() && pAtmoConfig->m_3dlut) ColorPacket = CAtmoTools::Apply3dlut(pAtmoConfig, ColorPacket); // our own trilinear CMS if(pAtmoConfig->isUseColorKWhiteAdj()) ColorPacket = CAtmoTools::ApplyColorK(pAtmoConfig, ColorPacket); // apply white calibration - only if it is not done by the hardware if((pAtmoConfig->isUseSoftwareWhiteAdj()))//&&(!pAtmoConfig->isUseColorKWhiteAdj())) ColorPacket = CAtmoTools::WhiteCalibration(pAtmoConfig, ColorPacket); //Sensitivity ColorPacket = CAtmoTools::ApplySens(pAtmoConfig, ColorPacket); /* send color data to the the hardware... */ try { pAtmoConnection->SendData(ColorPacket); delete (char *)ColorPacket; } catch(...) { 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; } }