DetachedAudacious::~DetachedAudacious() noexcept
{
    CommonUtilities::exceptionsToStderr([this] {
        if (exitExternalPlayerOnQuit())
            exitPlayer();
    }, VENTUROUS_CORE_ERROR_PREFIX "In ~DetachedAudacious(): ");
}
int OMXPlayerSync::syncClient ( bool send )
{
   static bool slowDown=false;
   static bool speedUp=false;
   sockaddr_in srv;
   socklen_t slen=sizeof( srv );
   if ( syncType == SYNC_CLIENT )
   {
      clientTime = stamp;
      do {

      if( send && server.sin_addr.s_addr != INADDR_ANY )
      {
          TimeSync ts;
          ts.source = 'C';
          ts.cTime = clientTime;
          ts.sTime = -1;

          if (-1 == sendto(sockfd, &ts, sizeof(ts), 0, (struct sockaddr*) &server, sizeof(server))) {
	     perror("1:send");
          }
      }
//      printf( "CLI: %10.2f SRV: %10.2f\r", clientTime, serverTime );

      bytesreceived = recvfrom(sockfd, buff, BUFFLEN, 0, (struct sockaddr *) &srv, &slen);
      if ( bytesreceived != -1 )
      {
	static float nextSecond = -1;
        if( ((TimeSync*)buff)->source == 'R' && clientTime >0 ) // Server response
	{
	    serverTime = ((TimeSync*)buff)->sTime;
	    if( ((TimeSync*)buff)->cTime != -1 )
	    {
		double diff = (serverTime-( ((TimeSync*)buff)->cTime + clientTime)/2)/(0.040*DVD_TIME_BASE);
		if( diff_sliding[2] == -1000.0 )
		{
		    diff_sliding[2] = diff;
		    diff_sliding[1] = diff;
		    diff_sliding[0] = diff;
		}
		else
		{
		    diff_sliding[2] = diff_sliding[1];
		    diff_sliding[1] = diff_sliding[0];
		    diff_sliding[0] = diff;
		}
                diff = (diff_sliding[0]+diff_sliding[1]+diff_sliding[2] )/3;
		printf( "D=%10.2f D0=%10.2f D1=%10.2f D2=%10.2f CLI: %10.2f CRT: %10.2f SRV: %10.2f\n",
		     diff,
		     diff_sliding[0],
		     diff_sliding[1],
		     diff_sliding[2],
		     clientTime,
		     ((TimeSync*)buff)->cTime,
		     serverTime );
		if( diff < -1.2 && !slowDown )
		{
//		    pauseMovie();
//		    usleep( (serverTime-( ((TimeSync*)buff)->cTime + clientTime)/2) );
printf("\nSLOW\n");
		    jitter = diff/70; // -1/50 = -0.02;
		    unpauseMovie();
		    speedUp = false;
		    slowDown = true;
		}
		if( diff > 0.5 && !speedUp )
		{
//		    pauseMovie();
printf("\nFAST\n");
		    jitter = diff /70; // 1/50 = 0.02;
		    unpauseMovie();
		    speedUp = true;
		    slowDown = false;
		}
		if( diff > -1.2 && slowDown )
		{
//		    pauseMovie();
printf("\nSLOW->NORMAL\n");
		    jitter = 0;
		    unpauseMovie();
		    slowDown = false;
		    speedUp = false;
		}
		if( diff < 0.5 && speedUp )
		{
//		    pauseMovie();
printf("\nFAST->NORMAL\n");
		    jitter = 0;
		    unpauseMovie();
		    slowDown = false;
		    speedUp = false;
		}
	    }
	}

     if( ((TimeSync*)buff)->source == 'E' ) // master exit
     {
	printf( "%d Master exit request\n", port );
        pause= false;
	exitPlayer();
     }

     if( ((TimeSync*)buff)->source == 'F' ) // Sound fade request
     {
	printf( "Sound fade request\n" );
	fadeSound();
     }

        if( ((TimeSync*)buff)->source == 'G' ) // Server play
	{
	    printf( "Client %d: Master play request\n", port );
	    serverTime = 0;
	    // resend down to DMX process
            sockaddr_in localhost;
            memset((void *) &localhost, 0, sizeof(struct sockaddr_in));
            localhost.sin_family = AF_INET;
            localhost.sin_port = htons( port+3 ); // send to DMX controller
            localhost.sin_addr.s_addr = htonl( (127<<24)|(0<<16)|(0<<8)|1 );
            if (-1 == sendto(sockfd, buff, sizeof(TimeSync), 0, (struct sockaddr*) &localhost, sizeof(localhost)) )
            {
	      perror("1:send");
            }
            pause = false;
	}

        if( ((TimeSync*)buff)->source == 'S' ) // Server broadcast
	{
            // store server address
            server.sin_addr.s_addr = srv.sin_addr.s_addr;
//printf( "CLI: %10.2f SRV: %10.2f\n", clientTime, serverTime );
	    serverTime = ((TimeSync*)buff)->sTime;
	    // resend down to DMX process
            sockaddr_in localhost;
            memset((void *) &localhost, 0, sizeof(struct sockaddr_in));
            localhost.sin_family = AF_INET;
            localhost.sin_port = htons( port+3 ); // send to DMX controller
            localhost.sin_addr.s_addr = htonl( (127<<24)|(0<<16)|(0<<8)|1 );
            if (-1 == sendto(sockfd, buff, sizeof(TimeSync), 0, (struct sockaddr*) &localhost, sizeof(localhost)) )
            {
	      perror("1:send");
            }
/*        if( ((TimeSync*)buff)->source == 'G' ) // Server play
	{
	    serverTime = 0;
	    // resend down to DMX process
            sockaddr_in localhost;
            memset((void *) &localhost, 0, sizeof(struct sockaddr_in));
            localhost.sin_family = AF_INET;
            localhost.sin_port = htons( port+3 ); // send to DMX controller
            localhost.sin_addr.s_addr = htonl( (127<<24)|(0<<16)|(0<<8)|1 );
            if (-1 == sendto(sockfd, buff, sizeof(TimeSync), 0, (struct sockaddr*) &localhost, sizeof(localhost))) {
	      perror("1:send");
            pause = false;
	}*/
	if( nextSecond == -1 )
	{
	    nextSecond = DVD_TIME_BASE*(long long)( (serverTime+2000000)/DVD_TIME_BASE );
	    printf( "NS=%f\n", nextSecond );
	}

	if( pause && 0 <= serverTime && serverTime <= 100000 )
	{
	    JumpToPos( 200000 ); // +0.2s ???
	    pause = false;
	    atPlayUnpause();
	    printf( "Synchro start\n" );
	}

//	printf( "P: %d NS:%f SRC: %c  CLI: %10.2f SRV: %10.2f\n", pause, nextSecond, ((TimeSync*)buff)->source, clientTime, serverTime );
// Jump to current server position
	if( pause && nextSecond != -1 && nextSecond <= serverTime-200000 ) // 1/10c
	{
	    JumpToPos( nextSecond );
	    pause=false;
	    atPlayUnpause();
	    printf( "NS=%f ST=%f\n", nextSecond, serverTime );
	}

	}
// End of jump

	//if( 0 <= serverTime && serverTime < 100000 )
	//    pause=false;
	}
	usleep( 1000 );
      }
      while( pause );
   }
   
   return 0;
}
int OMXPlayerSync::syncServer ()
{
   sockaddr_in ca;
   socklen_t slen=sizeof(ca);

   if ( syncType == SYNC_SERVER )
   {
    while( pause )
    {
     // Receive the tcp messages
     bytesreceived = recvfrom( sockfd, buff, BUFFLEN, 0, (struct sockaddr *) &ca, &slen);
     if ( -1 != bytesreceived) {
        if( ((TimeSync*)buff)->source == 'G' ) // master start
        {
            printf( "%d: Unpause movie\n", port );
            pause = false;
        }

        if( ((TimeSync*)buff)->source == 'E' ) // master exit
        {
            printf( "%d Master exit request\n", port );
            pause= false;
            exitPlayer();
        }
     }
     usleep( 1000 );
    }

     // Broadcast current position
// printf( "FR: %f\r", serverTime );
     ServerBcast();

     // Receive the tcp messages
     bytesreceived = recvfrom( sockfd, buff, BUFFLEN, 0, (struct sockaddr *) &ca, &slen);
     if (-1 == bytesreceived) {
        return 1;
     }

     if( ((TimeSync*)buff)->source == 'E' ) // master exit
     {
        printf( "%d Master exit request\n", port );
        pause= false;
        exitPlayer();
     }

     // then rapidly send a message back
     if( ((TimeSync*)buff)->source == 'C' ) // client request
     {
/*	printf("F:%d P:%d A:%d.%d.%d.%d\n", ca.sin_family, ca.sin_port,
	    ((ca.sin_addr.s_addr) & 0xFF), ((ca.sin_addr.s_addr>>8) & 0xFF), 
	    ((ca.sin_addr.s_addr>>16) & 0xFF), ((ca.sin_addr.s_addr>>24) & 0xFF) );
*/
         TimeSync ts;
         ts.source = 'R';
         ts.cTime = ((TimeSync*)buff)->cTime;
         ts.sTime = serverTime;
         if( -1 == sendto(sockfd, &ts, sizeof(ts), 0, (struct sockaddr*) &ca, slen) )
         {
            perror("0:send parent");
            return 1;
         }
     }

     if( ((TimeSync*)buff)->source == 'G' ) // master go
     {
	printf( "Master play request\n" );
	unpauseMovie();
     }

     if( ((TimeSync*)buff)->source == 'F' ) // Sound fade request
     {
	printf( "Sound fade request\n" );
	fadeSound();
     }
     pause = false;
   }
}