Пример #1
0
bool CDVDClock::Update(double clock, double absolute, double limit, const char* log)
{
  CExclusiveLock lock(m_critSection);
  double was_absolute = SystemToAbsolute(m_startClock);
  double was_clock    = m_iDisc + absolute - was_absolute;
  lock.Leave();

  double error = std::abs(clock - was_clock);

  // skip minor updates while speed adjust is active
  // -> adjusting buffer levels
  if (m_speedAdjust != 0 && error < DVD_MSEC_TO_TIME(100))
  {
    return false;
  }
  else if (error > limit)
  {
    Discontinuity(clock, absolute);

    CLog::Log(LOGDEBUG, "CDVDClock::Discontinuity - %s - was:%f, should be:%f, error:%f"
                      , log
                      , was_clock
                      , clock
                      , clock - was_clock);
    return true;
  }
  else
    return false;
}
Пример #2
0
double CDVDClock::ErrorAdjust(double error, const char* log)
{
  CSingleLock lock(m_critSection);

  double clock, absolute, adjustment;
  clock = GetClock(absolute);

  // skip minor updates while speed adjust is active
  // -> adjusting buffer levels
  if (m_speedAdjust != 0 && error < DVD_MSEC_TO_TIME(100))
  {
    return 0;
  }

  adjustment = error;

  if (m_vSyncAdjust != 0)
  {
    if (error > 0.5 * m_frameTime)
      adjustment = m_frameTime;
    else if (error < -0.5 * m_frameTime)
      adjustment = -m_frameTime;
    else
      adjustment = 0;
  }

  if (adjustment == 0)
    return 0;

  Discontinuity(clock+adjustment, absolute);

  CLog::Log(LOGDEBUG, "CDVDClock::ErrorAdjust - %s - error:%f, adjusted:%f",
                      log, error, adjustment);
  return adjustment;
}
Пример #3
0
static int Flush(codecidct* p)
{
	Discontinuity(p);
	p->FrameEnd = 0;
	p->Dropping = 0;
	BufferClear(&p->Buffer);
	if (p->Flush)
		p->Flush(p);
	return ERR_NONE;
}
Пример #4
0
bool CDVDClock::Update(double clock, double absolute, double limit, const char* log)
{
  CExclusiveLock lock(m_critSection);
  double was_absolute = SystemToAbsolute(m_startClock);
  double was_clock    = m_iDisc + absolute - was_absolute;
  lock.Leave();
  if(std::abs(clock - was_clock) > limit)
  {
    Discontinuity(clock, absolute);

    CLog::Log(LOGDEBUG, "CDVDClock::Discontinuity - %s - was:%f, should be:%f, error:%f"
                      , log
                      , was_clock
                      , clock
                      , clock - was_clock);
    return true;
  }
  else
    return false;
}
Пример #5
0
double CDVDClock::ErrorAdjust(double error, const char* log)
{
  CSingleLock lock(m_critSection);

  double clock, absolute, adjustment;
  clock = GetClock(absolute);

  // skip minor updates while speed adjust is active
  // -> adjusting buffer levels
  if (m_speedAdjust != 0 && error < DVD_MSEC_TO_TIME(100))
  {
    return 0;
  }

  adjustment = error;

  if (m_vSyncAdjust != 0)
  {
    // Audio ahead is more noticeable then audio behind video.
    // Correct if aufio is more than 20ms ahead or more then
    // 27ms behind. In a worst case scenario we switch from
    // 20ms ahead to 21ms behind (for fps of 23.976)
    if (error > 0.02 * DVD_TIME_BASE)
      adjustment = m_frameTime;
    else if (error < -0.027 * DVD_TIME_BASE)
      adjustment = -m_frameTime;
    else
      adjustment = 0;
  }

  if (adjustment == 0)
    return 0;

  Discontinuity(clock+adjustment, absolute);

  CLog::Log(LOGDEBUG, "CDVDClock::ErrorAdjust - %s - error:%f, adjusted:%f",
                      log, error, adjustment);
  return adjustment;
}
Пример #6
0
static int Process(codecidct* p, const packet* Packet, const flowstate* State)
{
	int Result;
	idct* IDCT = p->IDCT.Ptr;

	if (p->IDCT.Count<=0 && p->IDCT.Width>0 && p->IDCT.Height>0)
		return ERR_INVALID_DATA;

	p->State.CurrTime = State->CurrTime;
	if (State->DropLevel > 1)
		Discontinuity(p);

	if (p->Show>=0) // pending frame?
	{
		Result = IDCT->Send(IDCT,p->RefTime,&p->State);
		if (Result == ERR_BUFFER_FULL)
			return Result;
		p->Show = -1;
	}

	if (!Packet) // end of file or dropped
		return IDCT->Null(IDCT,State,0);

	if ((p->In.Format.Video.Pixel.Flags & PF_FRAGMENTED) && p->FindNext)
	{
		bool_t Processed = 0;

		if (p->RefTime >= 0)
			p->RefTime += p->FrameTime; 

		for (;;)
		{
			if (!p->FindNext(p))
			{
				if (Processed)
				{
					Result = ERR_NEED_MORE_DATA;
					break;
				}

				p->FrameEnd -= p->Buffer.ReadPos;
				BufferPack(&p->Buffer,0);
				BufferWrite(&p->Buffer,Packet->Data[0],Packet->Length,32768);
				Processed = 1;

				if (Packet->RefTime >= 0)
				{
					p->RefTime = Packet->RefTime;
//					if (p->IDCT.Count >= 3 && p->FrameTime>0 && p->RefTime >= p->FrameTime)
//						p->RefTime -= p->FrameTime;
				}
			}
			else
			{
				p->State.DropLevel = p->RefTime >= 0 && State->CurrTime >= 0 &&
				                     p->RefTime < (State->CurrTime - p->DropTolerance);

				if (State->DropLevel > 1)
				{
					p->IDCT.Ptr->Null(p->IDCT.Ptr,NULL,0);
					Result = ERR_NONE;
				}
				else
					Result = p->Frame(p,p->Buffer.Data+p->Buffer.ReadPos,p->FrameEnd-p->Buffer.ReadPos); 

				p->Buffer.ReadPos = p->FrameEnd;

				if (Result==ERR_NONE && p->Show>=0)
				{
					if (!Processed)
						Result = ERR_BUFFER_FULL; // resend packet next time
					break;
				}
			}
		}
	}
	else
	{
		if (State->DropLevel > 1)
		{
			p->IDCT.Ptr->Null(p->IDCT.Ptr,NULL,0);
			Result = ERR_NONE;
		}
		else
		{
			p->State.DropLevel = State->DropLevel;
			p->RefTime = Packet->RefTime;
//			if (p->IDCT.Count >= 3 && p->FrameTime>0 && p->RefTime >= p->FrameTime)
//				p->RefTime -= p->FrameTime;
			Result = p->Frame(p,Packet->Data[0],Packet->Length);
		}
	}

	if (p->Show>=0 && IDCT->Send(IDCT,p->RefTime,&p->State) != ERR_BUFFER_FULL)
		p->Show = -1;

	return Result;
}