Example #1
0
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;
}
Example #2
0
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;
		}
	}