Ejemplo n.º 1
0
AllocatorStatus_t   AllocatorSimple_c::Free(void)
{
	int              i;
	unsigned int         LocalBufferSize;
	unsigned int         MaxBlockSize;
	unsigned char       *LocalOffset;
	OS_LockMutex(&Lock);
	memset(Blocks, 0x00, sizeof(Blocks));
	LocalBufferSize     = BufferSize;
	LocalOffset         = NULL;
	MaxBlockSize        = 0x4000000 - ((uintptr_t)PhysicalAddress & 0x03ffffff);
	HighestUsedBlockIndex   = 0;
	for (i = 0; ((LocalBufferSize != 0) && (i < ALLOCATOR_SIMPLE_MAX_BLOCKS)); i++)
	{
		Blocks[i].InUse      = true;
		Blocks[i].Size       = min(LocalBufferSize, MaxBlockSize);
		Blocks[i].Base       = LocalOffset;
		LocalBufferSize     -= Blocks[i].Size;
		LocalOffset     += Blocks[i].Size;
		MaxBlockSize         = 0x4000000;
		HighestUsedBlockIndex    = i;
	}
	OS_SetEvent(&EntryFreed);
	OS_UnLockMutex(&Lock);
	return AllocatorNoError;
}
Ejemplo n.º 2
0
BufferStatus_t   BufferPool_Generic_c::AbortBlockingGetBuffer( void )
{
    AbortGetBuffer      = true;
    OS_SetEvent( &BufferReleaseSignal );

    return BufferNoError;
}
Ejemplo n.º 3
0
PlayerStatus_t Player_Generic_c::StreamStep(PlayerStream_t Stream)
{
	report(severity_info, "Player_Generic_c::StreamStep - Step\n");
	Stream->Step = true;
	OS_SetEvent(&Stream->SingleStepMayHaveHappened);
	return PlayerNoError;
}
Ejemplo n.º 4
0
RingStatus_t   RingGeneric_c::Insert( unsigned int       Value )
{
unsigned int OldNextInsert;

    OS_LockMutex( &Lock );

    OldNextInsert       = NextInsert;
    Storage[NextInsert] = Value;

    NextInsert++;
    if( NextInsert == Limit )
	NextInsert = 0;

    if( NextInsert == NextExtract )
    {
	NextInsert      = OldNextInsert;
	OS_UnLockMutex( &Lock );
	return RingTooManyEntries;
    }

    OS_UnLockMutex( &Lock );
    OS_SetEvent( &Signal );

    return RingNoError;
}
Ejemplo n.º 5
0
AllocatorSimple_c::~AllocatorSimple_c(void)
{
	BeingDeleted        = true;
	OS_SetEvent(&EntryFreed);
	while (InAllocate)
		OS_SleepMilliSeconds(1);
	OS_TerminateEvent(&EntryFreed);
	OS_TerminateMutex(&Lock);
}
Ejemplo n.º 6
0
RingGeneric_c::~RingGeneric_c( void )
{
    OS_SetEvent( &Signal );
    OS_SleepMilliSeconds( 1 );

    OS_TerminateMutex( &Lock );
    OS_TerminateEvent( &Signal );

    if( Storage != NULL )
	delete Storage;
}
Ejemplo n.º 7
0
PlayerStatus_t Player_Generic_c::CleanUpAfterStream(PlayerStream_t Stream)
{
	PlayerStream_t *PointerToStream;
	unsigned int OwnerIdentifier;
	Buffer_t Buffer;
	//
	// Shut down the processes
	//
	OS_ResetEvent(&Stream->StartStopEvent);
	Stream->DiscardingUntilMarkerFramePostM = true;
	Stream->DiscardingUntilMarkerFrameDtoM = true;
	Stream->DiscardingUntilMarkerFramePtoD = true;
	Stream->DiscardingUntilMarkerFrameCtoP = true;
	Stream->Collator->DiscardAccumulatedData();
	Stream->Collator->Halt();
	Stream->FrameParser->Halt();
	Stream->Codec->OutputPartialDecodeBuffers();
	Stream->Codec->ReleaseReferenceFrame(CODEC_RELEASE_ALL);
	Stream->Codec->Halt();
	Stream->OutputTimer->Halt();
	if (Stream->Manifestor != NULL)
	{
		Stream->Manifestor->QueueNullManifestation();
		Stream->Manifestor->Halt();
	}
	Stream->Terminating = true;
	OS_SetEvent(&Stream->SingleStepMayHaveHappened); // Just in case they are waiting for a single step
	if (Stream->ProcessRunningCount != 0)
	{
		OS_WaitForEvent(&Stream->StartStopEvent, 2 * PLAYER_MAX_EVENT_WAIT);
		if (Stream->ProcessRunningCount != 0)
			report(severity_error, "Player_Generic_c::CleanUpAfterStream - Stream processes failed to terminate (%d).\n", Stream->ProcessRunningCount);
	}
	//
	// Strip the rings - NOTE we assume we are the first owner on any buffer
	//
	if (Stream->CollatedFrameRing != NULL)
	{
		while (Stream->CollatedFrameRing->NonEmpty())
		{
			Stream->CollatedFrameRing->Extract((unsigned int *)(&Buffer));
			Buffer->GetOwnerList(1, &OwnerIdentifier);
			Buffer->DecrementReferenceCount(OwnerIdentifier);
		}
		delete Stream->CollatedFrameRing;
	}
//
	if (Stream->ParsedFrameRing != NULL)
	{
		while (Stream->ParsedFrameRing->NonEmpty())
		{
			Stream->ParsedFrameRing->Extract((unsigned int *)(&Buffer));
			Buffer->GetOwnerList(1, &OwnerIdentifier);
			Buffer->DecrementReferenceCount(OwnerIdentifier);
		}
		delete Stream->ParsedFrameRing;
	}
//
	if (Stream->DecodedFrameRing != NULL)
	{
		while (Stream->DecodedFrameRing->NonEmpty())
		{
			Stream->DecodedFrameRing->Extract((unsigned int *)(&Buffer));
			Buffer->GetOwnerList(1, &OwnerIdentifier);
			Buffer->DecrementReferenceCount(OwnerIdentifier);
		}
		delete Stream->DecodedFrameRing;
	}
//
	if (Stream->ManifestedBufferRing != NULL)
	{
		while (Stream->ManifestedBufferRing->NonEmpty())
		{
			Stream->ManifestedBufferRing->Extract((unsigned int *)(&Buffer));
			Buffer->GetOwnerList(1, &OwnerIdentifier);
			Buffer->DecrementReferenceCount(OwnerIdentifier);
		}
		delete Stream->ManifestedBufferRing;
	}
	//
	// Extract from playback list
	//
	OS_LockMutex(&Lock);
	for (PointerToStream = &Stream->Playback->ListOfStreams;
			(*PointerToStream) != NULL;
			PointerToStream = &((*PointerToStream)->Next))
		if ((*PointerToStream) == Stream)
		{
			(*PointerToStream) = Stream->Next;
			break;
		}
	OS_UnLockMutex(&Lock);
	//
	// Now reset the individual classes
	//
	Stream->Collator->Reset();
	Stream->FrameParser->Reset();
	Stream->CodecReset = true;
	Stream->Codec->Reset();
	Stream->OutputTimer->Reset();
	Stream->Manifestor->Reset();
	OS_TerminateEvent(&Stream->StartStopEvent);
	OS_TerminateEvent(&Stream->Drained);
	OS_TerminateEvent(&Stream->SwitchStreamLastOneOutOfTheCodec);
	OS_TerminateEvent(&Stream->SingleStepMayHaveHappened);
	//
	// If the playback no longer has any streams, we reset the
	// output coordinator refreshing the registration of the player.
	//
	if (Stream->Playback->ListOfStreams == NULL)
	{
		Stream->Playback->OutputCoordinator->Halt();
		Stream->Playback->OutputCoordinator->Reset();
		Stream->Playback->OutputCoordinator->RegisterPlayer(this, Stream->Playback, PlayerAllStreams);
	}
	//
	// Delete the code frame buffer pool
	//
	if (Stream->CodedFrameBufferPool != NULL)
	{
		BufferManager->DestroyPool(Stream->CodedFrameBufferPool);
		Stream->CodedFrameBufferPool = NULL;
	}
	if (Stream->CodedFrameMemory[CachedAddress] != NULL)
	{
#if __KERNEL__
		AllocatorClose(Stream->CodedFrameMemoryDevice);
#endif
		Stream->CodedFrameMemory[CachedAddress] = NULL;
		Stream->CodedFrameMemory[UnCachedAddress] = NULL;
		Stream->CodedFrameMemory[PhysicalAddress] = NULL;
	}
	//
	// Delete the stream structure
	//
	delete Stream;
//
	return PlayerNoError;
}
Ejemplo n.º 8
0
// This is the coordinator task, the main beat for the tests comes from here.
void TestTask0(void)
{
	uint8_t ret,i;
	uint32_t ti,tj;
	uint16_t t;

	while(1)
	{
		switch(testcase)
		{
			case 0:
				// Task Priority
				assert(testvar ==0);
				testvar++;
				break;
			case 1:
				// Timer / Wait
				OS_WaitTicks(OSALMTest0, 3);

				t=10;
				OS_GetTicks(&ti); // get time
				OS_WaitTicks(OSALMTest0, t);
				OS_GetTicks(&tj); // get time
				assert(tj-ti == t); // waited time was correct
				break;
			case 2:
				// WaitEvent
				// SetEvent
// wait for A, then A occurs
				testvar =0;
				OS_WaitTicks(OSALMTest0, 10);
				assert(testvar==1);
				OS_SetEvent(OSTestTskID1,1<<0);
				OS_WaitTicks(OSALMTest0, 2);
				assert(testvar==2);
// A occurs, then wait for A
				testvar =3;
				OS_SetEvent(OSTestTskID1,1<<0);
				assert(testvar==3);
				OS_WaitTicks(OSALMTest0, 100); // other task wastes time...
				assert(testvar==4);
// wait for more events, one occurs, then the other
				OS_SetEvent(OSTestTskID1,1<<2);
				assert(testvar==4);
				OS_WaitTicks(OSALMTest0, 10);
				assert(testvar==6);
				OS_SetEvent(OSTestTskID1,1<<1);
				assert(testvar==6);
				OS_WaitTicks(OSALMTest0, 10);
				assert(testvar==8);

				break;
			case 3:
				// MutexGet
				// MutexRelease			

				break;
			case 4:
				// QueueIn
				// QueueOut
				OS_WaitTicks(OSALMTest0, 50);
				for (i=0;i<20;i++) // forward
				{
					ret = OS_QueueIn(&TestQ,&i);
					assert(ret==0);
				}
				OS_SetEvent(OSTestTskID1,1<<6);
				OS_WaitTicks(OSALMTest0, 50);
				for (i=20;i>0;i--) // backward
				{
					ret = OS_QueueIn(&TestQ,&i);
					assert(ret==0);
				}
				OS_SetEvent(OSTestTskID1,1<<6);
				OS_WaitTicks(OSALMTest0, 50);
				
				// check, if q is empty
				t = OS_GetQueueSpace(&TestQ);
				assert(t==64);
					
								
				for (i=0;i<64;i++) // overload the Q
				{
					ret = OS_QueueIn(&TestQ,&i);
					assert(ret==0);
				}
				
				// check, if none left
				t = OS_GetQueueSpace(&TestQ);
				assert(t==0);				
				
				// now one too much:
				ret = OS_QueueIn(&TestQ,&i);
				assert(ret==1);

				break;
			case 5:
				// SetAlarm
				// WaitAlarm
				OS_SetAlarm(OSALMTest1,53);
				OS_SetAlarm(OSALMTest2,44);
				break;
			case 6:
				// Event with timeout
				OS_SetEvent(OSTestTskID1,1<<3);
				OS_WaitTicks(OSALMTest0, 50);
				// do not set the second one...
				
				break;
			case 7:
				//queue long test
				ret = OS_QueueOut(&TestQLong,(uint8_t*)&ti); // Q empty
				assert(ret == 1);
				for (i=0;i<10;i++)
				{
					ret = OS_QueueIn(&TestQLong,(uint8_t*)&longQtest[i]);
					assert (ret==0);
				}
				ret = OS_QueueIn(&TestQLong,(uint8_t*)&longQtest[9]);
				assert (ret==1); // Q full
				for (i=0;i<10;i++)
				{
					ret = OS_QueueOut(&TestQLong,(uint8_t*)&ti);
					assert(ret==0);
					assert(ti == longQtest[i]);
				}
				ret = OS_QueueOut(&TestQLong,(uint8_t*)&ti);
				assert(ret==1); // q empty

				break;
			case 8:
				// Nested Mutexes
				OS_MutexGet(0);
				WasteOfTime(1);
				OS_MutexGet(1);
				WasteOfTime(1);
				OS_MutexRelease(0);
				WasteOfTime(1);
				OS_MutexRelease(1);
				assert(1==1); // if it doesnt work, we do not come to here,
				
				break;
			case 9:
				// test of OS_GetUnusedStack (uint8_t TaskID)

				t=OS_GetUnusedStack(OSTestTskID0); // task0
				assert(t>80 && t<150);

				t=OS_GetUnusedStack(OSTestTskID1); // task1
				assert(t>80 && t<150);

				t=OS_GetUnusedStack(OSTestTskID2); // task2
				assert(t>80 && t<150);

				t=OS_GetUnusedStack(5); // idle
				assert(t>2000 && t<2600);


				break;
			case 10:
				OS_GetTicks(&ti);
				OS_SetAlarm(OSALMTest0,39);
				OS_SetAlarm(OSALMTest3,64);
				OS_WaitAlarm(OSALMTest0);
				OS_GetTicks(&tj);
				assert(tj-ti == 39);
				OS_WaitAlarm(OSALMTest3);
				OS_GetTicks(&tj);
				assert(tj-ti == 64);

				break;
			case 11:
				assert(0); // just for proofing that it works!

				break;
			default:
				// The END
				while(1)
				{
					// sit here and wait for someone picking up the results out of "TestResults". 0 = OK. 
					// "TestProcessed" shows the number of processed assertions.
					asm("break");
				}
				break;
		}

		OS_WaitTicks(OSALMTest0, 500); // wait for tests to be processed...

		testcase++;
		OS_SetEvent(OSTestTskID1,1<<7); // tick other tasks in sync.
		OS_SetEvent(OSTestTskID2,1<<7);
	}//while(1)


}
Ejemplo n.º 9
0
void TestTask2(void)
{
	uint32_t ts,te;
	uint32_t i,j;
	uint16_t t;
	while(1)
	{
		switch(testcase)
		{
			case 0:
				// Task Priority
				assert(testvar ==2);
				testvar++;
				break;
			case 1:
				// Timer / Wait
				OS_WaitTicks(OSALMTest2, 2);
				
				t=50;
				OS_GetTicks(&i); // get time
				OS_WaitTicks(OSALMTest2, t);
				OS_GetTicks(&j); // get time
				assert(j-i == t); // waited time was correct
				break;
			case 2:
				// WaitEvent
				// SetEvent

				break;
			case 3:
				// MutexGet
				// MutexRelease			
				// two cases: 
				// 1:mutex is occupied by higher prio
				WasteOfTime(10);
				OS_MutexGet(0);
				testvar = 7;
				WasteOfTime(50);
				assert(testvar == 7);
				OS_MutexRelease(0);
				OS_SetEvent(OSTestTskID1,1<<1);
				// 2:mutex is occupied
				OS_MutexGet(0);
				testvar = 4;
				WasteOfTime(50);
				assert(testvar == 4);
				OS_MutexRelease(0);


				break;
			case 4:
				// QueueIn
				// QueueOut

				break;
			case 5:
				// SetAlarm
				// WaitAlarm
				OS_GetTicks(&ts);
				OS_WaitAlarm(OSALMTest2);
				OS_GetTicks(&te);
				assert(te-ts == 44);

				break;
			case 6:
				// Event with timeout


				break;
			case 7:
				// long queue


				break;
			default:
				break;
		}
	OS_WaitEvent(1<<7);
	}// while(1)

}
Ejemplo n.º 10
0
ManifestorStatus_t Manifestor_Audio_c::QueueDecodeBuffer(class Buffer_c *Buffer)
{
	ManifestorStatus_t Status;
	BufferStatus_t BufferStatus;
	unsigned int BufferIndex;
	//MANIFESTOR_DEBUG(">><<\n");
	AssertComponentState("Manifestor_Audio_c::QueueDecodeBuffer", ComponentRunning);
	//
	// Obtain the index for the buffer and populate the parameter data.
	//
	BufferStatus = Buffer->GetIndex(&BufferIndex);
	if (BufferStatus != BufferNoError)
	{
		MANIFESTOR_ERROR("Unable to lookup buffer index %x.\n", BufferStatus);
		return ManifestorError;
	}
	StreamBuffer[BufferIndex].Buffer = Buffer;
	StreamBuffer[BufferIndex].EventPending = EventPending;
	EventPending = false;
	BufferStatus = Buffer->ObtainMetaDataReference(Player->MetaDataParsedFrameParametersReferenceType,
						       (void **) &StreamBuffer[BufferIndex].FrameParameters);
	if (BufferStatus != BufferNoError)
	{
		MANIFESTOR_ERROR("Unable to access buffer parsed frame parameters %x.\n", BufferStatus);
		return ManifestorError;
	}
	BufferStatus = Buffer->ObtainMetaDataReference(Player->MetaDataParsedAudioParametersType,
						       (void **) &StreamBuffer[BufferIndex].AudioParameters);
	if (BufferStatus != BufferNoError)
	{
		MANIFESTOR_ERROR("Unable to access buffer parsed audio parameters %x.\n", BufferStatus);
		return ManifestorError;
	}
	Buffer->DumpToRelayFS(ST_RELAY_TYPE_DECODED_AUDIO_BUFFER, ST_RELAY_SOURCE_AUDIO_MANIFESTOR + RelayfsIndex, (void *)Player);
	BufferStatus = Buffer->ObtainMetaDataReference(Player->MetaDataAudioOutputTimingType,
						       (void **) &StreamBuffer[BufferIndex].AudioOutputTiming);
	if (BufferStatus != BufferNoError)
	{
		MANIFESTOR_ERROR("Unable to access buffer audio output timing parameters %x.\n", BufferStatus);
		return ManifestorError;
	}
	BufferStatus = Buffer->ObtainDataReference(NULL, NULL,
						   (void **)(&StreamBuffer[BufferIndex].Data), UnCachedAddress);
	if (BufferStatus != BufferNoError)
	{
		MANIFESTOR_ERROR("Unable to obtain buffer's data reference %x.\n", BufferStatus);
		return ManifestorError;
	}
	StreamBuffer[BufferIndex].QueueAsCodedData = true;
	//
	// Check if there are new audio parameters (i.e. change of sample rate etc.) and note this
	//
	if (0 == memcmp(&LastSeenAudioParameters, StreamBuffer[BufferIndex].AudioParameters,
			sizeof(LastSeenAudioParameters)))
	{
		StreamBuffer[BufferIndex].UpdateAudioParameters = false;
	}
	else
	{
		StreamBuffer[BufferIndex].UpdateAudioParameters = true;
		memcpy(&LastSeenAudioParameters, StreamBuffer[BufferIndex].AudioParameters,
		       sizeof(LastSeenAudioParameters));
	}
	//
	// Allow the sub-class to have a peek at the buffer before we queue it for display
	//
	Status = QueueBuffer(BufferIndex);
	if (Status != ManifestorNoError)
	{
		MANIFESTOR_ERROR("Unable to queue buffer %x.\n", Status);
		return Status;
	}
	//
	// Enqueue the buffer for display within the playback thread
	//
	OS_LockMutex(&BufferQueueLock);
	QueuedBufferCount++;
	StreamBuffer[BufferIndex].NextIndex = INVALID_BUFFER_ID; // end marker
	if (BufferQueueHead == INVALID_BUFFER_ID)
	{
		BufferQueueHead = BufferIndex;
	}
	else
	{
		StreamBuffer[BufferQueueTail].NextIndex = BufferIndex;
	}
	BufferQueueTail = BufferIndex;
	OS_UnLockMutex(&BufferQueueLock);
	OS_SetEvent(&BufferQueueUpdated);
	return ManifestorNoError;
}
Ejemplo n.º 11
0
//}}}  
//{{{  ~HavanaPlayer_c
HavanaPlayer_c::~HavanaPlayer_c (void)
{
    int                         i;
    class  HavanaFactory_c*     Factory;

    HAVANA_DEBUG("\n");


    // remove event signal
    Player->SetEventSignal (PlayerAllPlaybacks, PlayerAllStreams, EventAllEvents, NULL);

    // Shut down event signal thread first
    if (EventSignalThreadId != OS_INVALID_THREAD)
    {
        EventSignalThreadRunning        = false;
        EventSignalCallback             = NULL;
        OS_SetEvent (&EventSignal);
        OS_WaitForEvent (&EventSignalThreadTerminated, OS_INFINITE);       // Wait for display signal to exit
        EventSignalThreadId             = OS_INVALID_THREAD;
        OS_TerminateEvent (&EventSignalThreadTerminated);
        OS_TerminateEvent (&EventSignal);
        OS_TerminateMutex (&Lock);
    }

    for (i = 0; i < MAX_PLAYBACKS; i++)
    {
        if (Playback[i] != NULL)
            delete Playback[i];
    }
    for (i = 0; i < MAX_DEMUX_CONTEXTS; i++)
    {
        if (DemuxContext[i] != NULL)
            delete DemuxContext[i];
    }
    for (i = 0; i < MAX_DISPLAYS; i++)
    {
        if (AudioDisplays[i] != NULL)
            delete AudioDisplays[i];
        if (VideoDisplays[i] != NULL)
            delete VideoDisplays[i];
        if (OtherDisplays[i] != NULL)
            delete OtherDisplays[i];
    }

    if (BufferManager != NULL)
        delete BufferManager;
    if (Demultiplexor != NULL)
        delete Demultiplexor;

    while (FactoryList != NULL)
    {
        Factory         = FactoryList;
        FactoryList     = Factory->Next ();
        delete Factory;
    }

    DisplayDevice       = NULL;

    EventSignalCallback = NULL;

}
Ejemplo n.º 12
0
PlayerStatus_t   Player_Generic_c::SetEventSignal(
    PlayerPlayback_t          Playback,
    PlayerStream_t            Stream,
    PlayerEventMask_t         Events,
    OS_Event_t               *Event )
{
    unsigned int      i;
    PlayerStatus_t    Status;
    unsigned int     *PtrToIndex;

    //
    // Split into two paths, are we clearing a signal registration, or setting one
    //

    if( Event == NULL )
    {
        for( i=0; i<PLAYER_MAX_EVENT_SIGNALS; i++ )
            if( (ExternalEventSignals[i].Signal         != NULL)        &&
                    (ExternalEventSignals[i].Playback       == Playback)    &&
                    (ExternalEventSignals[i].Stream         == Stream)      &&
                    (ExternalEventSignals[i].Events         == Events) )
            {
                ExternalEventSignals[i].Signal  = NULL;
                return PlayerNoError;
            }

        report( severity_error, "Player_Generic_c::SetEventSignal - Exact match not found for clearing event signal.\n" );
        return PlayerMatchNotFound;
    }
    else

        //
        // Setting a new signal, first find a free entry and set it
        // Then check if there is an event record in the queue that
        // reuskts in us setting this event.
        //

    {

        OS_LockMutex( &Lock );

        for( i=0; i<PLAYER_MAX_EVENT_SIGNALS; i++ )
            if( ExternalEventSignals[i].Signal == NULL )
            {
                ExternalEventSignals[i].Playback        = Playback;
                ExternalEventSignals[i].Stream          = Stream;
                ExternalEventSignals[i].Events          = Events;
                ExternalEventSignals[i].Signal          = Event;
                break;
            }

        OS_UnLockMutex( &Lock );

        if( i == PLAYER_MAX_EVENT_SIGNALS )
        {
            report( severity_error, "Player_Generic_c::SetEventSignal - Attempt to set too many signal conditions.\n" );
            return PlayerToMany;
        }

//

        Status  = ScanEventListForMatch( Playback, Stream, Events, &PtrToIndex );
        if( Status == PlayerNoError )
            OS_SetEvent( Event );
    }

//

    return PlayerNoError;
}
Ejemplo n.º 13
0
AllocatorStatus_t   AllocatorSimple_c::Free(unsigned int      Size,
		unsigned char    *Block)
{
	unsigned int    i;
	unsigned int    LowestFreeBlock;
	unsigned int    NextHighestUsedBlockIndex;
//
	Size                    = (((Size + SegmentSize - 1) / SegmentSize) * SegmentSize);
	LowestFreeBlock         = HighestUsedBlockIndex + 1;
	NextHighestUsedBlockIndex   = 0;
	OS_LockMutex(&Lock);
	//
	// Note by adding adjacent block records to the one we are trying to free,
	// this loop does concatenation of free blocks as well as freeing the
	// current block.
	//
	for (i = 0; i < (HighestUsedBlockIndex + 1); i++)
	{
		if (Blocks[i].InUse)
		{
			if (((Block + Size) == Blocks[i].Base) &&
					!On64MBBoundary(Blocks[i].Base))
			{
				Size            += Blocks[i].Size;
				Blocks[i].InUse  = false;
			}
			else if ((Block == (Blocks[i].Base + Blocks[i].Size)) &&
					 !On64MBBoundary(Block))
			{
				Size            += Blocks[i].Size;
				Block            = Blocks[i].Base;
				Blocks[i].InUse  = false;
			}
			else
			{
				NextHighestUsedBlockIndex   = i;
			}
		}
		if (!Blocks[i].InUse)
		{
			LowestFreeBlock      = min(LowestFreeBlock, i);
		}
	}
//
	if (LowestFreeBlock == ALLOCATOR_SIMPLE_MAX_BLOCKS)
	{
		report(severity_error, "AllocatorSimple_c::Free - Unable to create a free block - too many.\n");
		{
			report(severity_info, "\tBlocks\n");
			for (i = 0; i < ALLOCATOR_SIMPLE_MAX_BLOCKS; i++)
				if (Blocks[i].InUse)
					report(severity_info, "        %08x - %06x\n", Blocks[i].Base, Blocks[i].Size);
		}
		OS_SetEvent(&EntryFreed);
		OS_UnLockMutex(&Lock);
		return AllocatorError;
	}
//
	Blocks[LowestFreeBlock].InUse       = true;
	Blocks[LowestFreeBlock].Size        = Size;
	Blocks[LowestFreeBlock].Base        = Block;
	HighestUsedBlockIndex       = max(LowestFreeBlock, NextHighestUsedBlockIndex);
//
	OS_SetEvent(&EntryFreed);
	OS_UnLockMutex(&Lock);
	return AllocatorNoError;
}
void   Player_Generic_c::ProcessDecodeToManifest(       PlayerStream_t            Stream )
{
unsigned int                      i;
PlayerStatus_t                    Status;
RingStatus_t                      RingStatus;
unsigned int                      AccumulatedBufferTableOccupancy;
PlayerBufferRecord_t             *AccumulatedBufferTable;
Buffer_t                          Buffer = NULL;
Buffer_t                          OriginalCodedFrameBuffer;
BufferType_t                      BufferType;
PlayerControlStructure_t         *ControlStructure;
ParsedFrameParameters_t          *ParsedFrameParameters;
unsigned int                      LowestIndex;
unsigned int                      LowestDisplayFrameIndex;
unsigned int                      DesiredFrameIndex;
unsigned int			  PossibleDecodeBuffers;
unsigned int                      MaxDecodesOutOfOrder;
PlayerSequenceNumber_t           *SequenceNumberStructure;
unsigned long long                LastEntryTime;
unsigned long long                SequenceNumber;
unsigned long long                MinumumSequenceNumberAccumulated;
unsigned long long                MaximumActualSequenceNumberSeen;
unsigned long long                Time;
unsigned int                      AccumulatedBeforeControlMessagesCount;
unsigned int                      AccumulatedAfterControlMessagesCount;
bool                              SequenceCheck;
bool                              ProcessNow;
unsigned int                     *Count;
PlayerBufferRecord_t             *Table;
Buffer_t                          MarkerFrameBuffer;
bool                              FirstFrame;
bool                              DiscardBuffer;
bool				  LastPreManifestDiscardBuffer;
unsigned char                     SubmitInitialFrame;
Buffer_t                          InitialFrameBuffer;

    //
    // Set parameters
    //

    AccumulatedBufferTableOccupancy             = 0;
    AccumulatedBufferTable                      = Stream->AccumulatedDecodeBufferTable;

    LastEntryTime                               = OS_GetTimeInMicroSeconds();
    SequenceNumber                              = INVALID_SEQUENCE_VALUE;
    Time                                        = INVALID_TIME;
    AccumulatedBeforeControlMessagesCount       = 0;
    AccumulatedAfterControlMessagesCount        = 0;

    MinumumSequenceNumberAccumulated		= 0xffffffffffffffffULL;
    MaximumActualSequenceNumberSeen             = 0;
    DesiredFrameIndex                           = 0;
    FirstFrame                                  = true;

    MarkerFrameBuffer                           = NULL;
    InitialFrameBuffer				= NULL;

    LastPreManifestDiscardBuffer		= false;

    //
    // Signal we have started
    //

    OS_LockMutex( &Lock );

    Stream->ProcessRunningCount++;

    if( Stream->ProcessRunningCount == Stream->ExpectedProcessCount )
	OS_SetEvent( &Stream->StartStopEvent );

    OS_UnLockMutex( &Lock );

    //
    // Main Loop
    //

    while( !Stream->Terminating )
    {
	//
	// Buffer re-ordering loop
	//

	while( !Stream->Terminating )
	{
	    //
	    // Scan the list of accumulated buffers to see if the next display frame is available
	    // (whether because it was already accumulated, or because its display frame index has been updated)
	    //

	    MinumumSequenceNumberAccumulated    = 0xffffffffffffffffULL;
	    if( AccumulatedBufferTableOccupancy != 0 )
	    {
		LowestIndex                     = INVALID_INDEX;
		LowestDisplayFrameIndex         = INVALID_INDEX;
		for( i=0; i<Stream->NumberOfDecodeBuffers; i++ )
		    if( AccumulatedBufferTable[i].Buffer != NULL )
		    {
			MinumumSequenceNumberAccumulated        = min(MinumumSequenceNumberAccumulated, AccumulatedBufferTable[i].SequenceNumber);

			if( (AccumulatedBufferTable[i].ParsedFrameParameters->DisplayFrameIndex != INVALID_INDEX)       &&
			    ((LowestIndex == INVALID_INDEX) || (AccumulatedBufferTable[i].ParsedFrameParameters->DisplayFrameIndex < LowestDisplayFrameIndex)) )
			{
			    LowestDisplayFrameIndex     = AccumulatedBufferTable[i].ParsedFrameParameters->DisplayFrameIndex;
			    LowestIndex                 = i;
			}
		    }

		Stream->Manifestor->GetDecodeBufferCount( &PossibleDecodeBuffers );
		MaxDecodesOutOfOrder		= (Stream->Playback->Direction == PlayForward) ? (PossibleDecodeBuffers >> 1) : (3 * PossibleDecodeBuffers)/4;
		MaxDecodesOutOfOrder		= min( (PossibleDecodeBuffers - PLAYER_MINIMUM_NUMBER_OF_WORKING_DECODE_BUFFERS), MaxDecodesOutOfOrder );
		if( Stream->Playback->Direction == PlayForward )
		    MaxDecodesOutOfOrder	= min( PLAYER_LIMIT_ON_OUT_OF_ORDER_DECODES, MaxDecodesOutOfOrder );

		if( (LowestIndex != INVALID_INDEX) &&
		    (   (LowestDisplayFrameIndex == DesiredFrameIndex) || 
			(AccumulatedBufferTableOccupancy >= MaxDecodesOutOfOrder) ||
			(AccumulatedBufferTable[LowestIndex].ParsedFrameParameters->CollapseHolesInDisplayIndices) ||
			(MarkerFrameBuffer != NULL) ) )
		{
		    Buffer                                                      = AccumulatedBufferTable[LowestIndex].Buffer;
		    ParsedFrameParameters                                       = AccumulatedBufferTable[LowestIndex].ParsedFrameParameters;
		    SequenceNumber                                              = AccumulatedBufferTable[LowestIndex].SequenceNumber;
		    BufferType                                                  = Stream->DecodeBufferType;
		    AccumulatedBufferTable[LowestIndex].Buffer                  = NULL;
		    AccumulatedBufferTable[LowestIndex].ParsedFrameParameters   = NULL;
		    AccumulatedBufferTableOccupancy--;
		    break;
		}
	    }

	    //
	    // Skip any frame indices that were unused
	    //

	    while( CheckForNonDecodedFrame( Stream, DesiredFrameIndex ) )
		DesiredFrameIndex++;

	    //
	    // If we get here with a marker frame, then we have emptied our accumulated list
	    //

	    if( MarkerFrameBuffer != NULL )
	    {
		SequenceNumber                          = SequenceNumberStructure->Value;
		MaximumActualSequenceNumberSeen		= max(SequenceNumber, MaximumActualSequenceNumberSeen);
		ProcessAccumulatedControlMessages(  Stream, 
						    &AccumulatedBeforeControlMessagesCount,
						    PLAYER_MAX_DTOM_MESSAGES,
						    Stream->AccumulatedBeforeDtoMControlMessages, 
						    SequenceNumber, Time );

		ProcessAccumulatedControlMessages(  Stream,
						    &AccumulatedAfterControlMessagesCount,
						    PLAYER_MAX_DTOM_MESSAGES,
						    Stream->AccumulatedAfterDtoMControlMessages, 
						    SequenceNumber, Time );

		Stream->ManifestedBufferRing->Insert( (unsigned int)MarkerFrameBuffer );        // Pass on the marker
		MarkerFrameBuffer                       = NULL;
		Stream->DiscardingUntilMarkerFrameDtoM  = false;
		continue;
	    }

	    //
	    // Get a new buffer (continue will still perform the scan)
	    //

	    RingStatus  = Stream->DecodedFrameRing->Extract( (unsigned int *)(&Buffer), PLAYER_NEXT_FRAME_EVENT_WAIT );
	    if( (RingStatus == RingNothingToGet) || (Buffer == NULL) || Stream->Terminating )
		continue;

	    Buffer->TransferOwnership( IdentifierProcessDecodeToManifest );
	    Buffer->GetType( &BufferType );
	    if( BufferType != Stream->DecodeBufferType )
		break;

	    //
	    // Obtain a sequence number from the buffer
	    //

	    Status      = Buffer->ObtainAttachedBufferReference( Stream->CodedFrameBufferType, &OriginalCodedFrameBuffer );
	    if( Status != PlayerNoError )
	    {
		report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Unable to obtain the the original coded frame buffer - Implementation error\n" );
		Buffer->DecrementReferenceCount( IdentifierProcessDecodeToManifest );
		continue;
	    }

	    Status      = OriginalCodedFrameBuffer->ObtainMetaDataReference( MetaDataSequenceNumberType, (void **)(&SequenceNumberStructure) );
	    if( Status != PlayerNoError )
	    {
		report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Unable to obtain the meta data \"SequenceNumber\" - Implementation error\n" );
		Buffer->DecrementReferenceCount( IdentifierProcessDecodeToManifest );
		continue;
	    }

	    SequenceNumberStructure->TimeEntryInProcess2        = OS_GetTimeInMicroSeconds();
	    SequenceNumberStructure->DeltaEntryInProcess2       = SequenceNumberStructure->TimeEntryInProcess2 - LastEntryTime;
	    LastEntryTime                                       = SequenceNumberStructure->TimeEntryInProcess2;
	    SequenceNumber                                      = SequenceNumberStructure->Value;

	    //
	    // Check, is this a marker frame
	    //

	    if( SequenceNumberStructure->MarkerFrame )
	    {
		MarkerFrameBuffer       = Buffer;
		continue;                       // allow us to empty the accumulated buffer list
	    }

	    //
	    // If this is the first seen decode buffer do we wish to offer it up as an initial frame
	    //

	    if( FirstFrame )
	    {
		FirstFrame              = false;
		SubmitInitialFrame      = PolicyValue( Stream->Playback, Stream, PolicyManifestFirstFrameEarly );
		if( SubmitInitialFrame == PolicyValueApply )
		{
		    Status      	= Stream->Manifestor->InitialFrame( Buffer );
		    if( Status != ManifestorNoError )
			report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Failed to apply InitialFrame action.\n" );

		    if( InitialFrameBuffer != NULL )
			Stream->Codec->ReleaseDecodeBuffer( InitialFrameBuffer );

		    InitialFrameBuffer	= Buffer;
		    InitialFrameBuffer->IncrementReferenceCount();
		}
	    }

	    //
	    // Do we want to insert this in the table
	    //

	    Status      = Buffer->ObtainMetaDataReference( MetaDataParsedFrameParametersReferenceType, (void **)(&ParsedFrameParameters) );
	    if( Status != PlayerNoError )
	    {
		report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Unable to obtain the meta data \"ParsedFrameParametersReference\" - Implementation error\n" );
		Buffer->DecrementReferenceCount( IdentifierProcessDecodeToManifest );
		continue;
	    }

#if 0
{
unsigned int A, B;
	Stream->DecodeBufferPool->GetPoolUsage( &A, &B, NULL, NULL, NULL );

report( severity_info, "Got(%d) %3d (R = %d, K = %d) %d, %016llx - %d %d/%d\n", Stream->StreamType, ParsedFrameParameters->DecodeFrameIndex, ParsedFrameParameters->ReferenceFrame, ParsedFrameParameters->KeyFrame, ParsedFrameParameters->DisplayFrameIndex, ParsedFrameParameters->NormalizedPlaybackTime, AccumulatedBufferTableOccupancy, B, A );
}
#endif
	    if( ParsedFrameParameters->DisplayFrameIndex <= DesiredFrameIndex )
		break;

	    for( i=0; i<Stream->NumberOfDecodeBuffers; i++ )
		if( AccumulatedBufferTable[i].Buffer == NULL )
		{
		    AccumulatedBufferTable[i].Buffer                    = Buffer;
		    AccumulatedBufferTable[i].SequenceNumber            = SequenceNumber;
		    AccumulatedBufferTable[i].ParsedFrameParameters     = ParsedFrameParameters;
		    AccumulatedBufferTableOccupancy++;
		    break;
		}

	    if( i >= Stream->NumberOfDecodeBuffers )
	    {
		report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Unable to insert buffer in table - Implementation error.\n" );
		break;  // Assume it is immediate, as an implementation error this is pretty nasty
	    }
	}

	if( Stream->Terminating )
	    continue;

	// --------------------------------------------------------------------------------------------
	// We now have a buffer after frame re-ordering
	//
	// First calculate the sequence number that applies to this frame
	// this calculation may appear wierd, the idea is this, assume you
	// have a video stream IPBB, sequence numbers 0 1 2 3, frame reordering
	// will yield sequence numbers 0 2 3 1 IE any command to be executed at
	// the end of the stream will appear 1 frame early, the calculations 
	// below will re-wossname the sequence numbers to 0 1 1 3 causing the 
	// signal to occur at the correct point.
	//

	//
	// Deal with a coded frame buffer 
	//

	if( BufferType == Stream->DecodeBufferType )
	{
	    //
	    // Report any re-ordering problems
	    //

	    if( ParsedFrameParameters->CollapseHolesInDisplayIndices && (ParsedFrameParameters->DisplayFrameIndex > DesiredFrameIndex) )
		DesiredFrameIndex	= ParsedFrameParameters->DisplayFrameIndex;

	    if( ParsedFrameParameters->DisplayFrameIndex > DesiredFrameIndex )
		report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Hole in display frame indices (Got %d Expected %d).\n", ParsedFrameParameters->DisplayFrameIndex, DesiredFrameIndex );

	    if( ParsedFrameParameters->DisplayFrameIndex < DesiredFrameIndex )
		report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Frame re-ordering failure (Got %d Expected %d) - Implementation error.\n", ParsedFrameParameters->DisplayFrameIndex, DesiredFrameIndex );

	    //
	    // First calculate the sequence number that applies to this frame
	    // this calculation may appear wierd, the idea is this, assume you
	    // have a video stream IPBB, sequence numbers 0 1 2 3, frame reordering
	    // will yield sequence numbers 0 2 3 1 IE any command to be executed at
	    // the end of the stream will appear 1 frame early, the calculations 
	    // below will re-wossname the sequence numbers to 0 1 1 3 causing the 
	    // signal to occur at the correct point.
	    //

	    MaximumActualSequenceNumberSeen     = max(SequenceNumber, MaximumActualSequenceNumberSeen);
	    SequenceNumber                      = min(MaximumActualSequenceNumberSeen, MinumumSequenceNumberAccumulated );

	    Time                                = ParsedFrameParameters->NativePlaybackTime;

	    //
	    // Process any outstanding control messages to be applied before this buffer
	    //

	    ProcessAccumulatedControlMessages(  Stream, 
						&AccumulatedBeforeControlMessagesCount,
						PLAYER_MAX_DTOM_MESSAGES,
						Stream->AccumulatedBeforeDtoMControlMessages, 
						SequenceNumber, Time );

	    //
	    // If we are paused, then we loop waiting for something to happen
	    //

	    if( Stream->Playback->Speed == 0 )
	    {
		while( (Stream->Playback->Speed == 0) && !Stream->Step && !Stream->Terminating && !Stream->DiscardingUntilMarkerFrameDtoM )
		{
		    OS_WaitForEvent( &Stream->SingleStepMayHaveHappened, PLAYER_NEXT_FRAME_EVENT_WAIT );
		    OS_ResetEvent( &Stream->SingleStepMayHaveHappened );
		}

		Stream->Step    = false;
	    }

	    //
	    // If we are not discarding everything, then procede to process the buffer
	    //

	    DiscardBuffer       = Stream->DiscardingUntilMarkerFrameDtoM;

	    //
	    // Handle output timing functions, await entry into the decode window, 
	    // Then check for frame drop (whether due to trick mode, or because 
	    // we are running late). 
	    // NOTE1 Indicating we are not before decode, means 
	    // reference frames can be dropped, we will simply not display them
	    // NOTE2 We may block in these functions, so it is important to 
	    // recheck flags
	    //

	    if( !DiscardBuffer )
	    {
		Status  = Stream->OutputTimer->TestForFrameDrop( Buffer, OutputTimerBeforeOutputTiming );

		if( Status == OutputTimerNoError )
		{
		    //
		    // Note we loop here if we are engaged in re-timing the decoded frames
		    //

		    while( !Stream->Terminating && Stream->ReTimeQueuedFrames )
			OS_SleepMilliSeconds( PLAYER_RETIMING_WAIT );

		    Stream->OutputTimer->GenerateFrameTiming( Buffer );
		    Status  = Stream->OutputTimer->TestForFrameDrop( Buffer, OutputTimerBeforeManifestation );
		}

		if( Stream->DiscardingUntilMarkerFrameDtoM ||
		    Stream->Terminating ||
		    (Status != OutputTimerNoError) )
		    DiscardBuffer       = true;

		if( (DiscardBuffer != LastPreManifestDiscardBuffer) &&
		    (Status        == OutputTimerUntimedFrame) )
		{
		    report( severity_error, "Discarding untimed frames.\n" );
		}
		LastPreManifestDiscardBuffer	= DiscardBuffer;

#if 0
		// Nick debug data
		if( Status != OutputTimerNoError )
		    report( severity_info, "Timer Discard(%d) %3d (before Manifest) %08x\n", Stream->StreamType, ParsedFrameParameters->DecodeFrameIndex, Status );
#endif
	    }

	    //
	    // Pass the buffer to the manifestor for manifestation
	    // we do not release our hold on this buffer, buffers passed
	    // to the manifestor always re-appear on its output ring.
	    // NOTE calculate next desired frame index before we 
	    // give away the buffer, because ParsedFrameParameters
	    // can become invalid after either of the calls below.
	    //

	    DesiredFrameIndex   = ParsedFrameParameters->DisplayFrameIndex + 1;

	    if( !DiscardBuffer )
	    {
		SequenceNumberStructure->TimePassToManifestor   = OS_GetTimeInMicroSeconds();

#if 0
{
static unsigned long long         LastOutputTime = 0;
static unsigned long long         LastOutputTime1 = 0;
VideoOutputTiming_t              *OutputTiming;
unsigned int                      C0,C1,C2,C3;

Buffer->ObtainMetaDataReference( MetaDataVideoOutputTimingType, (void **)&OutputTiming );
Stream->CodedFrameBufferPool->GetPoolUsage( &C0, &C1, NULL, NULL, NULL );
Stream->DecodeBufferPool->GetPoolUsage( &C2, &C3, NULL, NULL, NULL );
report( severity_info, "Ord %3d (R = %d, K = %d) %d, %6lld %6lld %6lld %6lld (%d/%d %d/%d) (%d %d) %6lld %6lld\n",
	ParsedFrameParameters->DecodeFrameIndex, ParsedFrameParameters->ReferenceFrame, ParsedFrameParameters->KeyFrame, ParsedFrameParameters->DisplayFrameIndex,
	OutputTiming->SystemPlaybackTime - SequenceNumberStructure->TimePassToManifestor,
	SequenceNumberStructure->TimePassToManifestor - SequenceNumberStructure->TimeEntryInProcess2,
	SequenceNumberStructure->TimePassToManifestor - SequenceNumberStructure->TimeEntryInProcess1,
	SequenceNumberStructure->TimePassToManifestor - SequenceNumberStructure->TimeEntryInProcess0,
	C0, C1, C2, C3,
	Stream->FramesToManifestorCount, Stream->FramesFromManifestorCount,
	OutputTiming->SystemPlaybackTime - LastOutputTime, ParsedFrameParameters->NormalizedPlaybackTime - LastOutputTime1 );

//Buffer->TransferOwnership( IdentifierProcessDecodeToManifest, IdentifierManifestor );
//if( (OutputTiming->SystemPlaybackTime - SequenceNumberStructure->TimePassToManifestor) > 0xffffffffULL )
//    Stream->DecodeBufferPool->Dump( DumpAll );

    LastOutputTime = OutputTiming->SystemPlaybackTime;
    LastOutputTime1 = ParsedFrameParameters->NormalizedPlaybackTime;

}
if( Stream->FramesToManifestorCount >= 55 )
{
OS_SleepMilliSeconds( 1000 );
report( severity_info, "Ord(%d) %3d (R = %d, K = %d) %d, %016llx %016llx\n", Stream->StreamType, ParsedFrameParameters->DecodeFrameIndex, ParsedFrameParameters->ReferenceFrame, ParsedFrameParameters->KeyFrame, ParsedFrameParameters->DisplayFrameIndex, ParsedFrameParameters->NormalizedPlaybackTime, ParsedFrameParameters->NativePlaybackTime );
OS_SleepMilliSeconds( 4000 );
}
#endif
		Stream->FramesToManifestorCount++;
		Status	= Stream->Manifestor->QueueDecodeBuffer( Buffer );

		if( Status != ManifestorNoError )
		    DiscardBuffer	= true;

		if( InitialFrameBuffer != NULL )
		{
		    Stream->Codec->ReleaseDecodeBuffer( InitialFrameBuffer );
		    InitialFrameBuffer	= NULL;
		}
	    }

	    if( DiscardBuffer )
	    {
		Stream->Codec->ReleaseDecodeBuffer( Buffer );

		if( Stream->Playback->Speed == 0 )
		    Stream->Step	= true;
	    }

	    //
	    // Process any outstanding control messages to be applied after this buffer
	    //

	    ProcessAccumulatedControlMessages(  Stream,
						&AccumulatedAfterControlMessagesCount,
						PLAYER_MAX_DTOM_MESSAGES,
						Stream->AccumulatedAfterDtoMControlMessages, 
						SequenceNumber, Time );
	}

	//
	// Deal with a player control structure
	//

	else if( BufferType == BufferPlayerControlStructureType )
	{
	    Buffer->ObtainDataReference( NULL, NULL, (void **)(&ControlStructure) );

	    ProcessNow  = (ControlStructure->SequenceType == SequenceTypeImmediate);
	    if( !ProcessNow )
	    {
		SequenceCheck   = (ControlStructure->SequenceType == SequenceTypeBeforeSequenceNumber) ||
				  (ControlStructure->SequenceType == SequenceTypeAfterSequenceNumber);

		ProcessNow      = SequenceCheck ? ((SequenceNumber != INVALID_SEQUENCE_VALUE) && (ControlStructure->SequenceValue <= MaximumActualSequenceNumberSeen)) :
						  ((Time           != INVALID_SEQUENCE_VALUE) && (ControlStructure->SequenceValue <= Time));
	    }

	    if( ProcessNow )
		ProcessControlMessage( Stream, Buffer, ControlStructure );
	    else
	    {
		if( (ControlStructure->SequenceType == SequenceTypeBeforeSequenceNumber) ||
		    (ControlStructure->SequenceType == SequenceTypeBeforePlaybackTime) )
		{
		    Count       = &AccumulatedBeforeControlMessagesCount;
		    Table       = Stream->AccumulatedBeforeDtoMControlMessages;
		}
		else
		{
		    Count       = &AccumulatedAfterControlMessagesCount;
		    Table       = Stream->AccumulatedAfterDtoMControlMessages;
		}

		AccumulateControlMessage( Buffer, ControlStructure, Count, PLAYER_MAX_DTOM_MESSAGES, Table );
	    }
	}
	else
	{
	    report( severity_error, "Player_Generic_c::ProcessDecodeToManifest - Unknown buffer type received - Implementation error.\n" );
	    Buffer->DecrementReferenceCount();
	}
    }
Ejemplo n.º 15
0
PlayerStatus_t Player_Generic_c::InternalDrainStream(
	PlayerStream_t Stream,
	bool NonBlocking,
	bool SignalEvent,
	void *EventUserData,
	PlayerPolicy_t PlayoutPolicy,
	bool ParseAllFrames)
{
	PlayerStatus_t Status;
	unsigned char PlayoutPolicyValue;
	PlayerEventRecord_t Event;
	Buffer_t MarkerFrame;
	CodedFrameParameters_t *CodedFrameParameters;
	PlayerSequenceNumber_t *SequenceNumberStructure;
	unsigned long long PlayoutTime;
	unsigned long long Delay;
	//
	// Read the appropriate policy
	//
	PlayoutPolicyValue = PolicyValue(Stream->Playback, Stream, PlayoutPolicy);
	//
	// If we are to discard data in the drain, then perform the flushing
	//
	if (PlayoutPolicyValue == PolicyValueDiscard)
	{
		Stream->DiscardingUntilMarkerFramePostM = true;
		Stream->DiscardingUntilMarkerFrameDtoM = true;
		Stream->DiscardingUntilMarkerFramePtoD = true;
		Stream->DiscardingUntilMarkerFrameCtoP = !ParseAllFrames;
		Stream->ReTimeQueuedFrames = false;
		OS_SetEvent(&Stream->SingleStepMayHaveHappened);
		Status = Stream->Collator->InputJump(true, false);
		Status = Stream->Codec->DiscardQueuedDecodes();
		Status = Stream->Codec->OutputPartialDecodeBuffers();
		Status = Stream->Manifestor->ReleaseQueuedDecodeBuffers();
	}
	//
	// Just in case there is another marker frame doing the rounds
	//
	if (Stream->MarkerInCodedFrameIndex != INVALID_INDEX)
	{
		Status = WaitForDrainCompletion(Stream, (PlayoutPolicyValue == PolicyValueDiscard));
		if (Status != PlayerNoError)
		{
			report(severity_error, "Player_Generic_c::InternalDrainStream - Unable to launch a marker frame - Implementation error.\n");
			MarkerFrame->DecrementReferenceCount();
			return PlayerImplementationError;
		}
	}
	//
	// Insert a marker frame into the processing ring
	//
	Status = Stream->CodedFrameBufferPool->GetBuffer(&MarkerFrame, IdentifierDrain, 0);
	if (Status != BufferNoError)
	{
		report(severity_error, "Player_Generic_c::InternalDrainStream - Unable to obtain a marker frame.\n");
		return Status;
	}
//
	Status = MarkerFrame->ObtainMetaDataReference(MetaDataCodedFrameParametersType, (void **)(&CodedFrameParameters));
	if (Status != BufferNoError)
	{
		report(severity_error, "Player_Generic_c::InternalDrainStream - Unable to obtain the meta data coded frame parameters.\n");
		MarkerFrame->DecrementReferenceCount();
		return Status;
	}
	memset(CodedFrameParameters, 0x00, sizeof(CodedFrameParameters_t));
//
	Status = MarkerFrame->ObtainMetaDataReference(MetaDataSequenceNumberType, (void **)(&SequenceNumberStructure));
	if (Status != PlayerNoError)
	{
		report(severity_error, "Player_Generic_c::InternalDrainStream - Unable to obtain the meta data \"SequenceNumber\" - Implementation error\n");
		MarkerFrame->DecrementReferenceCount();
		return Status;
	}
	Stream->DrainSequenceNumber = Stream->NextBufferSequenceNumber + PLAYER_MAX_RING_SIZE;
	SequenceNumberStructure->MarkerFrame = true;
	SequenceNumberStructure->Value = Stream->DrainSequenceNumber;
	//
	// Reset the event indicating draining and insert the marker into the flow
	//
	OS_ResetEvent(&Stream->Drained);
	MarkerFrame->GetIndex(&Stream->MarkerInCodedFrameIndex);
	Stream->CollatedFrameRing->Insert((unsigned int)MarkerFrame);
	//
	// Issue an in sequence synchronization reset
	//
	Status = CallInSequence(Stream, SequenceTypeBeforeSequenceNumber, Stream->DrainSequenceNumber, OutputTimerFnResetTimeMapping, PlaybackContext);
	if (Status != PlayerNoError)
	{
		report(severity_error, "Player_Generic_c::InternalDrainStream - Failed to issue call to reset synchronization.\n");
		return Status;
	}
	//
	// Do we want to raise a signal on drain completion
	//
	if (SignalEvent)
	{
		Event.Code = EventStreamDrained;
		Event.Playback = Stream->Playback;
		Event.Stream = Stream;
		Event.PlaybackTime = TIME_NOT_APPLICABLE;
		Event.UserData = EventUserData;
		Status = CallInSequence(Stream, SequenceTypeBeforeSequenceNumber, Stream->DrainSequenceNumber, ManifestorFnQueueEventSignal, &Event);
		if (Status != PlayerNoError)
		{
			report(severity_error, "Player_Generic_c::InternalDrainStream - Failed to issue call to signal drain completion.\n");
			return Status;
		}
	}
	//
	// Queue the setting of the internal event, when the stream is drained
	// this allows us to commence multiple stream drains in a playback shutdown
	// and then block on completion of them all.
	//
	Status = CallInSequence(Stream, SequenceTypeAfterSequenceNumber, Stream->DrainSequenceNumber, OSFnSetEventOnPostManifestation, &Stream->Drained);
	if (Status != PlayerNoError)
	{
		report(severity_error, "Player_Generic_c::InternalDrainStream - Failed to request OS_SetEvent.\n");
		return Status;
	}
	//
	// Are we a blocking/non-blocking call
	//
	if (!NonBlocking)
	{
		Status = WaitForDrainCompletion(Stream, (PlayoutPolicyValue == PolicyValueDiscard));
		if (Status != PlayerNoError)
		{
			report(severity_error, "Player_Generic_c::InternalDrainStream - Failed to drain within allowed time (%d %d %d %d).\n",
			       Stream->DiscardingUntilMarkerFrameCtoP, Stream->DiscardingUntilMarkerFramePtoD,
			       Stream->DiscardingUntilMarkerFrameDtoM, Stream->DiscardingUntilMarkerFramePostM);
			return PlayerTimedOut;
		}
		//
		// If this was a playout drain, then check when the last
		// queued frame will complete and wait for it to do so.
		//
		if (PlayoutPolicyValue == PolicyValuePlayout)
		{
			//
			// The last frame will playout when the next frame could be displayed
			//
			Status = Stream->Manifestor->GetNextQueuedManifestationTime(&PlayoutTime);
			Delay = (PlayoutTime - OS_GetTimeInMicroSeconds()) / 1000;
			if ((Status == ManifestorNoError) && inrange(Delay, 1, (unsigned long long)Abs(RoundedLongLongIntegerPart(PLAYER_MAX_PLAYOUT_TIME / Stream->Playback->Speed))))
			{
				report(severity_info, "Player_Generic_c::InternalDrainStream - Delay to manifest last frame is %lldms\n", Delay);
				OS_SleepMilliSeconds((unsigned int)Delay);
			}
		}
	}
//
	return PlayerNoError;
}
Ejemplo n.º 16
0
PlayerStatus_t Player_Generic_c::SetPlaybackSpeed(
	PlayerPlayback_t Playback,
	Rational_t Speed,
	PlayDirection_t Direction)
{
	PlayerStatus_t Status;
	unsigned long long Now;
	unsigned long long NormalizedTimeAtStartOfDrain;
	bool ReTimeQueuedFrames;
	PlayerStream_t Stream;
	unsigned char Policy;
	//
	// Ensure that the playback interval is not cluttered by reversal clamps
	//
	Playback->PresentationIntervalReversalLimitStartNormalizedTime = INVALID_TIME;
	Playback->PresentationIntervalReversalLimitEndNormalizedTime = INVALID_TIME;
	//
	// Are we performing a direction flip
	//
	if (Playback->Direction != Direction)
	{
		//
		// Find the current playback time
		//
		Now = OS_GetTimeInMicroSeconds();
		Status = Playback->OutputCoordinator->TranslateSystemTimeToPlayback(PlaybackContext, Now, &NormalizedTimeAtStartOfDrain);
		if (Status != PlayerNoError)
		{
			report(severity_error, "Player_Generic_c::SetPlaybackSpeed - Failed to translate system time to playback time.\n");
			NormalizedTimeAtStartOfDrain = INVALID_TIME;
		}
		//
		// Drain with prejudice, but ensuring all frames are parsed
		//
		if (Playback->Speed == 0)
			SetPlaybackSpeed(Playback, 1, Playback->Direction);
		InternalDrainPlayback(Playback, (PlayerPolicy_t)PolicyPlayoutAlwaysDiscard, true);
		//
		// Find the current frames on display, and clamp the play
		// interval to ensure we don't go too far in the flip.
		//
		Policy = PolicyValue(Playback, PlayerAllStreams, PolicyClampPlaybackIntervalOnPlaybackDirectionChange);
		if (Policy == PolicyValueApply)
		{
			if (Direction == PlayForward)
				Playback->PresentationIntervalReversalLimitStartNormalizedTime = NormalizedTimeAtStartOfDrain;
			else
				Playback->PresentationIntervalReversalLimitEndNormalizedTime = NormalizedTimeAtStartOfDrain;
		}
	}
	//
	// Do we need to re-time the queued frames
	//
	ReTimeQueuedFrames = (Playback->Direction == Direction) &&
			     (Playback->Speed != Speed);
	//
	// Record the new speed and direction
	//
	Playback->Speed = Speed;
	Playback->Direction = Direction;
	//
	// Specifically inform the output coordinator of the change
	//
	Status = Playback->OutputCoordinator->SetPlaybackSpeed(PlaybackContext, Speed, Direction);
	if (Status != PlayerNoError)
	{
		report(severity_info, "Player_Generic_c::SetPlaybackSpeed - failed to inform output cordinator of speed change.\n");
		return Status;
	}
	//
	// Perform queued frame re-timing, and release any single step waiters
	//
	for (Stream = Playback->ListOfStreams;
			Stream != NULL;
			Stream = Stream->Next)
	{
		if (ReTimeQueuedFrames)
		{
			Stream->ReTimeStart = OS_GetTimeInMicroSeconds();
			Stream->ReTimeQueuedFrames = true;
			Stream->Manifestor->ReleaseQueuedDecodeBuffers();
		}
		OS_SetEvent(&Stream->SingleStepMayHaveHappened);
	}
//
	return PlayerNoError;
}
Ejemplo n.º 17
0
PlayerStatus_t   Player_Generic_c::SignalEvent( PlayerEventRecord_t      *Record )
{
    unsigned int    i;

//

    OS_LockMutex( &Lock );

    //
    // Find an empty vessel
    //

    for( i=0; i<PLAYER_MAX_OUTSTANDING_EVENTS; i++ )
        if( EventList[i].Record.Code == EventIllegalIdentifier )
        {
            memcpy( &EventList[i].Record, Record, sizeof(PlayerEventRecord_t) );

            EventList[i].NextIndex      = INVALID_INDEX;

            if( EventListTail != INVALID_INDEX )
            {
                EventList[EventListTail].NextIndex      = i;
                EventListTail                           = i;
            }
            else
            {
                EventListHead                           = i;
                EventListTail                           = i;
            }
            break;
        }

    if( i == PLAYER_MAX_OUTSTANDING_EVENTS )
    {
        //
        // The easiest solution if there is no free slot, is to discard
        // the oldest event and then recurse into this function.
        //

        report( severity_error, "Player_Generic_c::SignalEvent - Discarding uncollected event (%08x)\n", EventList[EventListHead].Record.Code );
        EventList[EventListHead].Record.Code    = EventIllegalIdentifier;
        EventListHead                           = EventList[EventListHead].NextIndex;

        OS_UnLockMutex( &Lock );
        return SignalEvent( Record );
    }

    //
    // We are still locked, now we can see if any of the signals
    // that have been queued are interested in this event.
    //

    OS_SetEvent( &InternalEventSignal );

    for( i=0; i<PLAYER_MAX_EVENT_SIGNALS; i++ )
        if( (ExternalEventSignals[i].Signal != NULL) &&
                EventMatchesCriteria( Record, ExternalEventSignals[i].Playback, ExternalEventSignals[i].Stream, ExternalEventSignals[i].Events ) )
            OS_SetEvent( ExternalEventSignals[i].Signal );

//

    OS_UnLockMutex( &Lock );
    return PlayerNoError;
}
void   Player_Generic_c::ProcessPostManifest(	PlayerStream_t		  Stream )
{
PlayerStatus_t			  Status;
RingStatus_t			  RingStatus;
Buffer_t			  Buffer;
Buffer_t			  OriginalCodedFrameBuffer;
BufferType_t			  BufferType;
PlayerControlStructure_t	 *ControlStructure;
ParsedFrameParameters_t		 *ParsedFrameParameters;
PlayerSequenceNumber_t		 *SequenceNumberStructure;
unsigned long long		  LastEntryTime;
unsigned long long		  SequenceNumber;
unsigned long long                MaximumActualSequenceNumberSeen;
unsigned long long 		  Time;
unsigned int			  AccumulatedBeforeControlMessagesCount;
unsigned int			  AccumulatedAfterControlMessagesCount;
bool				  ProcessNow;
unsigned int			 *Count;
PlayerBufferRecord_t		 *Table;
VideoOutputTiming_t		 *OutputTiming;
unsigned long long		  Now;

//

    LastEntryTime				= OS_GetTimeInMicroSeconds();
    SequenceNumber				= INVALID_SEQUENCE_VALUE;
    MaximumActualSequenceNumberSeen             = 0;
    Time					= INVALID_TIME;
    AccumulatedBeforeControlMessagesCount	= 0;
    AccumulatedAfterControlMessagesCount	= 0;

    //
    // Signal we have started
    //

    OS_LockMutex( &Lock );

    Stream->ProcessRunningCount++;

    if( Stream->ProcessRunningCount == Stream->ExpectedProcessCount )
	OS_SetEvent( &Stream->StartStopEvent );

    OS_UnLockMutex( &Lock );

    //
    // Main Loop
    //

    while( !Stream->Terminating )
    {
	RingStatus	= Stream->ManifestedBufferRing->Extract( (unsigned int *)(&Buffer), PLAYER_MAX_EVENT_WAIT );

	Now	= OS_GetTimeInMicroSeconds();
	if( Stream->ReTimeQueuedFrames && ((Now - Stream->ReTimeStart) > PLAYER_MAX_TIME_IN_RETIMING) )
	    Stream->ReTimeQueuedFrames	= false;

	if( RingStatus == RingNothingToGet )
	    continue;

	Buffer->GetType( &BufferType );
	Buffer->TransferOwnership( IdentifierProcessPostManifest );

	//
	// Deal with a coded frame buffer 
	//

	if( BufferType == Stream->DecodeBufferType )
	{
	    Stream->FramesFromManifestorCount++;

#if 0  
{
	static unsigned long long         LastTime = 0;
	static unsigned long long         LastActualTime = 0;
	AudioOutputTiming_t              *OutputTiming;
	
	Buffer->ObtainMetaDataReference( MetaDataAudioOutputTimingType, (void **)&OutputTiming);
	
	report( severity_info, "Post Dn = %d, DS= %6lld, DAS = %6lld, S = %016llx,AS = %016llx\n",
	                OutputTiming->DisplayCount,
	                OutputTiming->SystemPlaybackTime - LastTime,
	                OutputTiming->ActualSystemPlaybackTime - LastActualTime,
	                OutputTiming->SystemPlaybackTime,
					OutputTiming->ActualSystemPlaybackTime );

    LastTime            = OutputTiming->SystemPlaybackTime;
    LastActualTime      = OutputTiming->ActualSystemPlaybackTime;
}
#endif
#if 0
{
static unsigned long long	  LastTime = 0;
static unsigned long long	  LastActualTime = 0;
VideoOutputTiming_t     	 *OutputTiming;

Buffer->ObtainMetaDataReference( MetaDataVideoOutputTimingType, (void **)&OutputTiming );

report( severity_info, "Post Dn = %d %d, I = %d, TFF = %d, DS= %6lld, DAS = %6lld, S = %016llx, AS = %016llx\n",
		OutputTiming->DisplayCount[0], OutputTiming->DisplayCount[1],
		OutputTiming->Interlaced, OutputTiming->TopFieldFirst,
		OutputTiming->SystemPlaybackTime - LastTime,
		OutputTiming->ActualSystemPlaybackTime - LastActualTime,
		OutputTiming->SystemPlaybackTime, OutputTiming->ActualSystemPlaybackTime );

    LastTime 		= OutputTiming->SystemPlaybackTime;
    LastActualTime 	= OutputTiming->ActualSystemPlaybackTime;
}
#endif

	    //
	    // Obtain a sequence number from the buffer
	    //

	    Status	= Buffer->ObtainAttachedBufferReference( Stream->CodedFrameBufferType, &OriginalCodedFrameBuffer );
	    if( Status != PlayerNoError )
	    {
	        report( severity_error, "Player_Generic_c::ProcessPostManifest - Unable to obtain the the original coded frame buffer - Implementation error\n" );
		Buffer->DecrementReferenceCount( IdentifierProcessPostManifest );
		continue;
	    }

	    Status	= OriginalCodedFrameBuffer->ObtainMetaDataReference( MetaDataSequenceNumberType, (void **)(&SequenceNumberStructure) );
	    if( Status != PlayerNoError )
	    {
	        report( severity_error, "Player_Generic_c::ProcessPostManifest - Unable to obtain the meta data \"SequenceNumber\" - Implementation error\n" );
		Buffer->DecrementReferenceCount( IdentifierProcessPostManifest );
		continue;
	    }

	    Status	= Buffer->ObtainMetaDataReference( MetaDataParsedFrameParametersReferenceType, (void **)(&ParsedFrameParameters) );
	    if( Status != PlayerNoError )
	    {
	        report( severity_error, "Player_Generic_c::ProcessPostManifest - Unable to obtain the meta data \"ParsedFrameParametersReference\" - Implementation error\n" );
		Buffer->DecrementReferenceCount( IdentifierProcessPostManifest );
		continue;
	    }

	    //
	    // Check for whether or not we are in re-timing
	    //

	    if( Stream->ReTimeQueuedFrames && !SequenceNumberStructure->MarkerFrame )
	    {
		Status	= Buffer->ObtainMetaDataReference( (Stream->StreamType == StreamTypeVideo ? MetaDataVideoOutputTimingType : MetaDataAudioOutputTimingType),
							   (void **)&OutputTiming );
		if( Status != PlayerNoError )
		{
	            report( severity_error, "Player_Generic_c::ProcessPostManifest - Unable to obtain the meta data \"%s\" - Implementation error\n",
				(Stream->StreamType == StreamTypeVideo ? "VideoOutputTiming" : "AudioOutputTiming") );
		    Buffer->DecrementReferenceCount( IdentifierProcessPostManifest );
		    continue;
		}

		if( ValidTime(OutputTiming->ActualSystemPlaybackTime) )
		{
		    Stream->ReTimeQueuedFrames	= false;
		}
		else
		{
		    Stream->OutputTimer->GenerateFrameTiming( Buffer );
		    Status  = Stream->OutputTimer->TestForFrameDrop( Buffer, OutputTimerBeforeManifestation );
		    if( !Stream->Terminating && (Status == OutputTimerNoError) )
		    {
			Stream->FramesToManifestorCount++;
			Stream->Manifestor->QueueDecodeBuffer( Buffer );
			continue;
		    }
		}
	    }

	    //
	    // Extract the sequence number, and write the timing statistics
	    //

//report( severity_info, "MQ Post Man %d - %d\n", Stream->StreamType, ParsedFrameParameters->DisplayFrameIndex );

	    SequenceNumberStructure->TimeEntryInProcess3	= OS_GetTimeInMicroSeconds();
	    SequenceNumberStructure->DeltaEntryInProcess3	= SequenceNumberStructure->TimeEntryInProcess3 - LastEntryTime;
	    LastEntryTime					= SequenceNumberStructure->TimeEntryInProcess3;
	    SequenceNumber					= SequenceNumberStructure->Value;
	    MaximumActualSequenceNumberSeen			= max(SequenceNumber, MaximumActualSequenceNumberSeen);
	    Time						= ParsedFrameParameters->NativePlaybackTime;

#ifndef __TDT__
	    ProcessStatistics( Stream, SequenceNumberStructure );
#endif

	    if( SequenceNumberStructure->MarkerFrame )
	    {
		Stream->DiscardingUntilMarkerFramePostM	= false;
		Time					= INVALID_TIME;
	    }

	    //
	    // Process any outstanding control messages to be applied before this buffer
	    //

	    ProcessAccumulatedControlMessages( 	Stream, 
						&AccumulatedBeforeControlMessagesCount,
						PLAYER_MAX_POSTM_MESSAGES,
						Stream->AccumulatedBeforePostMControlMessages, 
						SequenceNumber, Time );

	    //
	    // Pass buffer back into output timer
	    // and release the buffer.
	    //

	    if( !SequenceNumberStructure->MarkerFrame )
	    {
		Stream->OutputTimer->RecordActualFrameTiming( Buffer );
		Stream->Codec->ReleaseDecodeBuffer( Buffer );
	    }
	    else
		Buffer->DecrementReferenceCount( IdentifierProcessPostManifest );

	    //
	    // Process any outstanding control messages to be applied after this buffer
	    //

	    ProcessAccumulatedControlMessages( 	Stream,
						&AccumulatedAfterControlMessagesCount,
						PLAYER_MAX_POSTM_MESSAGES,
						Stream->AccumulatedAfterPostMControlMessages, 
						SequenceNumber, Time );
	}

	//
	// Deal with a player control structure
	//

	else if( BufferType == BufferPlayerControlStructureType )
	{
	    Buffer->ObtainDataReference( NULL, NULL, (void **)(&ControlStructure) );

	    ProcessNow	= (ControlStructure->SequenceType == SequenceTypeImmediate) ||
			  ((SequenceNumber != INVALID_SEQUENCE_VALUE) && (ControlStructure->SequenceValue <= MaximumActualSequenceNumberSeen));

	    if( ProcessNow )
		ProcessControlMessage( Stream, Buffer, ControlStructure );
	    else
	    {
		if( (ControlStructure->SequenceType == SequenceTypeBeforeSequenceNumber) ||
		    (ControlStructure->SequenceType == SequenceTypeBeforePlaybackTime) )
		{
		    Count	= &AccumulatedBeforeControlMessagesCount;
		    Table	= Stream->AccumulatedBeforePostMControlMessages;
		}
		else
		{
		    Count	= &AccumulatedAfterControlMessagesCount;
		    Table	= Stream->AccumulatedAfterPostMControlMessages;
		}

		AccumulateControlMessage( Buffer, ControlStructure, Count, PLAYER_MAX_POSTM_MESSAGES, Table );
	    }
	}
	else
	{
	    report( severity_error, "Player_Generic_c::ProcessPostManifest - Unknown buffer type received - Implementation error.\n" );
	    Buffer->DecrementReferenceCount();
	}
    }

    report( severity_info, "3333 Holding control strutures %d\n", AccumulatedBeforeControlMessagesCount + AccumulatedAfterControlMessagesCount );

    //
    // Make sur no one will wait for these
    //

    Stream->ReTimeQueuedFrames	= false;

    //
    // Signal we have terminated
    //

    OS_LockMutex( &Lock );

    Stream->ProcessRunningCount--;

    if( Stream->ProcessRunningCount == 0 )
	OS_SetEvent( &Stream->StartStopEvent );

    OS_UnLockMutex( &Lock );
}
PlayerStatus_t   Player_Generic_c::PerformInSequenceCall(
						PlayerStream_t            Stream,
						PlayerControlStructure_t *ControlStructure )
{
PlayerStatus_t  Status;

//

    Status      = PlayerNoError;                // We ignore the status for some specific functions

//

    switch( ControlStructure->InSequence.Fn )
    {
	case CodecFnOutputPartialDecodeBuffers:
		Stream->Codec->OutputPartialDecodeBuffers();
		break;

	case CodecFnReleaseReferenceFrame:
//report(severity_info, "Performing a release %d\n", ControlStructure->InSequence.UnsignedInt );
		Stream->Codec->ReleaseReferenceFrame( ControlStructure->InSequence.UnsignedInt );
		break;

	case FrameParserFnSetModuleParameters:
		Status  = Stream->FrameParser->SetModuleParameters( ControlStructure->InSequence.UnsignedInt,
								    ControlStructure->InSequence.Block );
		break;

	case CodecFnSetModuleParameters:
		Status  = Stream->Codec->SetModuleParameters(   ControlStructure->InSequence.UnsignedInt,
								ControlStructure->InSequence.Block );
		break;

	case ManifestorFnSetModuleParameters:
		Status  = Stream->Manifestor->SetModuleParameters(      ControlStructure->InSequence.UnsignedInt,
									ControlStructure->InSequence.Block );
		break;

	case ManifestorFnQueueEventSignal:
		Status  = Stream->Manifestor->QueueEventSignal(         &ControlStructure->InSequence.Event );
		break;

	case ManifestorVideoFnSetInputWindow:
		{
		    unsigned int *Words	= (unsigned int *)ControlStructure->InSequence.Block;
		    Status 		= ((Manifestor_Video_c *)Stream->Manifestor)->SetInputWindow( Words[0], Words[1], Words[2], Words[3] );
		}
		break;

	case ManifestorVideoFnSetOutputWindow:
		{
		    unsigned int *Words	= (unsigned int *)ControlStructure->InSequence.Block;
		    Status 		= ((Manifestor_Video_c *)Stream->Manifestor)->SetOutputWindow( Words[0], Words[1], Words[2], Words[3] );
		}
		break;

	case OutputTimerFnResetTimeMapping:
		Status	= Stream->OutputTimer->ResetTimeMapping();
		break;

	case OutputTimerFnSetModuleParameters:
		Status	= Stream->OutputTimer->SetModuleParameters( 	ControlStructure->InSequence.UnsignedInt,
							    		ControlStructure->InSequence.Block );
		break;

	case OSFnSetEventOnManifestation:
	case OSFnSetEventOnPostManifestation:
		OS_SetEvent( (OS_Event_t *)ControlStructure->InSequence.Pointer );
		break;

	case PlayerFnSwitchFrameParser:
		SwitchFrameParser( (PlayerStream_t)ControlStructure->InSequence.Pointer );
		break;

	case PlayerFnSwitchCodec:
		SwitchCodec( (PlayerStream_t)ControlStructure->InSequence.Pointer );
		break;

	case PlayerFnSwitchOutputTimer:
		SwitchOutputTimer( (PlayerStream_t)ControlStructure->InSequence.Pointer );
		break;

	case PlayerFnSwitchComplete:
		SwitchComplete( (PlayerStream_t)ControlStructure->InSequence.Pointer );
		break;

	default:
		report( severity_error, "Player_Generic_c::PerformInSequenceCall - Unsupported function call - Implementation error.\n" );
		Status  = PlayerNotSupported;
		break;
    }

//

    return Status;
}
Ejemplo n.º 20
0
/* 说明一下,IDLE的中断在串口无数据接收的情况下,是不会一直产生的,
   产生的条件是这样的,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,
   一断接收的数据断流,没有接收到数据,即产生IDLE中断。*/
UINT32 IO_DataUartISR(UINT32 data)
{
    static UINT32 index = 0;
    UINT16 rxc;
    UINT8 txc;
    UINT32 Fifodepth;
    UINT8* temp;

#if 1
    /*******************************************************/
    /*               handle RX interrupt                   */
    /*******************************************************/
    /* Service RX data ready as long as there is data in RX FIFO */
    if( USART_GetIntBitState(USART1, USART_INT_RBNE) != RESET)
    {
         USART_INT_Set( USART1, USART_INT_IDLEF, ENABLE );
        /* Read data from RX UART1 DR and store in buffer */
        rxc = USART_DataReceive(USART1) & 0xff;
        UartDev.DATA.RxBufWrPtr[index] = (UINT8)rxc;
        UartDev.DATA.RxBufCount++;
        index++;
        USART_ClearIntBitState(USART1, USART_INT_RBNE);
    }

    if( USART_GetIntBitState(USART1, USART_INT_IDLEF) != RESET)
    {
         USART_INT_Set(USART1, USART_INT_IDLEF, DISABLE );
         USART_ClearIntBitState(USART1, USART_INT_IDLEF);
			
        index = 0;
        temp = UartDev.DATA.RxBufRdPtr;
        UartDev.DATA.RxBufRdPtr = UartDev.DATA.RxBufWrPtr;
        UartDev.DATA.RxBufWrPtr = temp;
        OS_SetEvent(IO_EVENT_GROUP_ID, IO_UART_RXIND_FLG);
		   
    }

    /*******************************************************/
    /*                  handle TX interrupt                */
    /*******************************************************/
    if( USART_GetIntBitState(USART1, USART_INT_TBE) != RESET)
    {
        USART_ClearIntBitState(USART1, USART_INT_TBE);

        /* Init FIFO count */
        Fifodepth = UART_UART_TX_HW_FIFO_SIZE;

        /* Add data to TX UART FIFO until it is full */
        while((UartDev.DATA.TxBufCount != 0) && (Fifodepth > 0))
        {
            /* Write data byte to UART TX FIFO */
            /* Write one byte to the transmit data register */
            txc = *(UartDev.DATA.TxBufPtr);
            USART_DataSend( USART1 , txc );
            UartDev.DATA.TxBufPtr++;

            /* Decrement Tx Serial count */
            UartDev.DATA.TxBufCount--;

            /* Decrement FIFO count */
            Fifodepth--;
        }

        /* if we have send all character in fifo */
        if (UartDev.DATA.TxBufCount == 0 )
        {
            /* disable the USART1 Transmoit interrupt */
            USART_INT_Set(USART1, USART_INT_TBE, DISABLE );
            OS_SetEvent(IO_EVENT_GROUP_ID, IO_UART_TXRSP_FLG);
        }
    }
#else

    /*******************************************************/
    /*               handle RX interrupt                   */
    /*******************************************************/
    /* Service RX data ready as long as there is data in RX FIFO */
    if( USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        USART_ITConfig( USART1, USART_IT_IDLE, ENABLE );
        /* Read data from RX UART1 DR and store in buffer */
        rxc = USART_ReceiveData(USART1) & 0xff;
        UartDev.DATA.RxBufWrPtr[index] = (UINT8)rxc;
        UartDev.DATA.RxBufCount++;
        index++;
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }

    if( USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
    {
        USART_ClearITPendingBit(USART1, USART_IT_IDLE);
        USART_ITConfig(USART1, USART_IT_IDLE, DISABLE );

        index = 0;
        temp = UartDev.DATA.RxBufRdPtr;
        UartDev.DATA.RxBufRdPtr = UartDev.DATA.RxBufWrPtr;
        UartDev.DATA.RxBufWrPtr = temp;
        OS_SetEvent(IO_EVENT_GROUP_ID, IO_UART_RXIND_FLG);
    }

    /*******************************************************/
    /*                  handle TX interrupt                */
    /*******************************************************/
    if( USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
    {
        USART_ClearITPendingBit(USART1, USART_IT_TXE);

        /* Init FIFO count */
        Fifodepth = UART_UART_TX_HW_FIFO_SIZE;

        /* Add data to TX UART FIFO until it is full */
        while((UartDev.DATA.TxBufCount != 0) && (Fifodepth > 0))
        {
            /* Write data byte to UART TX FIFO */
            /* Write one byte to the transmit data register */
            txc = *(UartDev.DATA.TxBufPtr);
            USART_SendData( USART1 , txc );
            UartDev.DATA.TxBufPtr++;

            /* Decrement Tx Serial count */
            UartDev.DATA.TxBufCount--;

            /* Decrement FIFO count */
            Fifodepth--;
        }

        /* if we have send all character in fifo */
        if (UartDev.DATA.TxBufCount == 0 )
        {
            /* Enable the USART1 Transmoit interrupt */
            USART_ITConfig(USART1, USART_IT_TXE, DISABLE );
            OS_SetEvent(IO_EVENT_GROUP_ID, IO_UART_TXRSP_FLG);
        }
    }
#endif
    return 0;
}
Ejemplo n.º 21
0
BufferStatus_t   BufferPool_Generic_c::ReleaseBuffer(
						Buffer_t          Buffer )
{
unsigned int             i;
Buffer_Generic_t         LocalBuffer;
Buffer_Generic_t        *LocationOfBufferPointer;
BlockDescriptor_t       *LocationOfBlockPointer;
BlockDescriptor_t        Block;
PlayerEventRecord_t      ReleaseEvent;

//

    LocalBuffer         = (Buffer_Generic_t)Buffer;

    //
    // Do I want to signal this free ?
    //

    if( (EventMask & EventBufferRelease) != 0 )
    {
	ReleaseEvent.Code                       = EventBufferRelease;
	ReleaseEvent.Playback                   = Playback;
	ReleaseEvent.Stream                     = Stream;
	ReleaseEvent.PlaybackTime               = TIME_NOT_APPLICABLE;
	ReleaseEvent.Value[0].Pointer           = LocalBuffer->BufferBlock->Address[0];
	if( ReleaseEvent.Value[0].Pointer == NULL )
	    ReleaseEvent.Value[0].Pointer       = LocalBuffer->BufferBlock->Address[1];
	if( ReleaseEvent.Value[0].Pointer == NULL )
	    ReleaseEvent.Value[0].Pointer       = LocalBuffer->BufferBlock->Address[2];
	ReleaseEvent.Value[1].UnsignedInt       = LocalBuffer->BufferBlock->Size;
	ReleaseEvent.UserData                   = EventUserData;

	Player->SignalEvent( &ReleaseEvent );
    }

    //
    // Release any non-persistant meta data
    //

    LocationOfBlockPointer        = &LocalBuffer->ListOfMetaData;
    while( *LocationOfBlockPointer != NULL )
    {
	if( !((*LocationOfBlockPointer)->AttachedToPool) )
	{
	    //
	    // Unthread the meta data item block
	    //

	    Block                       = *LocationOfBlockPointer;
	    *LocationOfBlockPointer     = Block->Next;

	    DeAllocateMemoryBlock( Block );
	    delete Block;
	}
	else
	    LocationOfBlockPointer      = &((*LocationOfBlockPointer)->Next);
    }

    //
    // Release our hold on any attached buffers
    //

    OS_LockMutex( &LocalBuffer->Lock );
    for( i=0; i<MAX_ATTACHED_BUFFERS; i++ )
    {
	Buffer_t	Temporary	= LocalBuffer->AttachedBuffers[i];
	if( Temporary != NULL )
	{
	    LocalBuffer->AttachedBuffers[i]     = NULL;
	    Temporary->DecrementReferenceCount();
	}
    }
    OS_UnLockMutex( &LocalBuffer->Lock );

    //
    // If non-persistant delete the memory associated with the block
    //

    if( !BufferDescriptor->AllocateOnPoolCreation && (BufferDescriptor->AllocationSource != NoAllocation) )
	DeAllocateMemoryBlock( LocalBuffer->BufferBlock );

    OS_LockMutex( &Lock );
    TotalUsedMemory		-= LocalBuffer->DataSize;
    LocalBuffer->DataSize        = 0;

    //
    // If there are a fixed number of buffers insert this on the ring, 
    // else unthread from list and delete the buffer
    //

    if( NumberOfBuffers != NOT_SPECIFIED )
    {
	FreeBuffer->Insert( (unsigned int)LocalBuffer );
	OS_SetEvent( &BufferReleaseSignal );
    }
    else
    {
	for( LocationOfBufferPointer     = &ListOfBuffers;
	     *LocationOfBufferPointer   != NULL;
	     LocationOfBufferPointer     = &((*LocationOfBufferPointer)->Next) )
	    if( (*LocationOfBufferPointer) == LocalBuffer )
		break;

	if( *LocationOfBufferPointer == NULL )
	{
	    report( severity_error, "BufferPool_Generic_c::ReleaseBuffer - Buffer not found in list, internal consistency error.\n" );
	    return BufferError;
	}

	*LocationOfBufferPointer        = LocalBuffer->Next;

	delete LocalBuffer;
	CountOfBuffers--;
    }

    CountOfReferencedBuffers--;
    OS_UnLockMutex( &Lock );

//

    return BufferNoError;
}
Ejemplo n.º 22
0
//}}}  
//{{{  EventSignalThread
void  HavanaPlayer_c::EventSignalThread (void)
{
    PlayerStatus_t              PlayerStatus;
    struct PlayerEventRecord_s  PlayerEvent;
    HavanaStatus_t              HavanaStatus;
    int                         i;
    struct player_event_s       Event;

    HAVANA_DEBUG("Starting\n");

    while (EventSignalThreadRunning)
    {
        OS_WaitForEvent (&EventSignal, OS_INFINITE);
        OS_ResetEvent   (&EventSignal);

        while (true)
        {
            PlayerStatus        = Player->GetEventRecord (PlayerAllPlaybacks, PlayerAllStreams, EventAllEvents, &PlayerEvent, true);
            if (PlayerStatus != PlayerNoError)
                break;

            HAVANA_DEBUG("Got Event 0x%x\n", PlayerEvent.Code);

            OS_LockMutex (&Lock);                       // Make certain we cannot delete playback while checking the event
            for (i = 0; i < MAX_PLAYBACKS; i++)         // Check to see if any streams are interested in this event
            {
                if (Playback[i] != NULL)
                {
                    HavanaStatus    = Playback[i]->CheckEvent (&PlayerEvent);
                    if (HavanaStatus == HavanaNoError)  // A stream has claimed event don't try any more.
                        break;
                }
            }
            OS_UnLockMutex (&Lock);

            if ((EventSignalThreadRunning) && (EventSignalCallback != NULL))
            //{{{  translate from a Player2 event record to the external Player event record.
            {
                Event.timestamp                 = PlayerEvent.PlaybackTime;
                Event.component                 = PlayerEvent.Value[0].Pointer;
                Event.playback                  = PlayerEvent.Playback;
                Event.stream                    = PlayerEvent.Stream;
                switch (PlayerEvent.Code)
                {
                    case EventPlaybackCreated:
                        Event.code              = PLAYER_EVENT_PLAYBACK_CREATED;
                        break;

                    case EventPlaybackTerminated:
                        Event.code              = PLAYER_EVENT_PLAYBACK_TERMINATED;
                        break;

                    case EventStreamCreated:
                        Event.code              = PLAYER_EVENT_STREAM_CREATED;
                        break;

                    case EventStreamTerminated:
                        Event.code              = PLAYER_EVENT_STREAM_TERMINATED;
                        break;

                    case EventStreamSwitched:
                        Event.code              = PLAYER_EVENT_STREAM_SWITCHED;
                        break;

                    case EventStreamDrained:
                        Event.code              = PLAYER_EVENT_STREAM_DRAINED;
                        break;

                    case EventStreamUnPlayable:
                        Event.code              = PLAYER_EVENT_STREAM_UNPLAYABLE;
                        break;

                    case EventFirstFrameManifested:
		        Event.code              = PLAYER_EVENT_FIRST_FRAME_ON_DISPLAY;
			break;

                    case EventTimeNotification:
                        Event.code              = PLAYER_EVENT_TIME_NOTIFICATION;
                        break;

                    case EventDecodeBufferAvailable:
                        Event.code              = PLAYER_EVENT_DECODE_BUFFER_AVAILABLE;
                        break;

                    case EventInputFormatCreated:
                        Event.code              = PLAYER_EVENT_INPUT_FORMAT_CREATED;
                        break;

                    case EventSupportedInputFormatCreated:
                        Event.code              = PLAYER_EVENT_SUPPORTED_INPUT_FORMAT_CREATED;
                        break;

                    case EventDecodeErrorsCreated:
                        Event.code              = PLAYER_EVENT_DECODE_ERRORS_CREATED;
                        break;

                    case EventSampleFrequencyCreated:
                        Event.code              = PLAYER_EVENT_SAMPLE_FREQUENCY_CREATED;
                        break;

                    case EventNumberChannelsCreated:
                        Event.code              = PLAYER_EVENT_NUMBER_CHANNELS_CREATED;
                        break;

                    case EventNumberOfSamplesProcessedCreated:
                        Event.code              = PLAYER_EVENT_NUMBER_OF_SAMPLES_PROCESSED;
                        break;

                    case EventInputFormatChanged:
                        Event.code              = PLAYER_EVENT_INPUT_FORMAT_CHANGED;
                        break;

                    case EventSourceSizeChangeManifest:
                        Event.code              = PLAYER_EVENT_SIZE_CHANGED;
                        break;

                    case EventSourceFrameRateChangeManifest:
                        Event.code              = PLAYER_EVENT_FRAME_RATE_CHANGED;
                        break;

                    case EventFailedToDecodeInTime:
                        Event.code              = PLAYER_EVENT_FRAME_DECODED_LATE;
                        break;

                    case EventFailedToDeliverDataInTime:
                        Event.code              = PLAYER_EVENT_DATA_DELIVERED_LATE;
                        break;

                    case EventBufferRelease:
                        Event.code              = PLAYER_EVENT_BUFFER_RELEASE;
                        break;

                    case EventTrickModeDomainChange:
                        Event.code              = PLAYER_EVENT_TRICK_MODE_CHANGE;
                        break;

                    case EventTimeMappingEstablished:
                        Event.code              = PLAYER_EVENT_TIME_MAPPING_ESTABLISHED;
                        break;

                    case EventTimeMappingReset:
                        Event.code              = PLAYER_EVENT_TIME_MAPPING_RESET;
                        break;

                    case EventFailureToPlaySmoothReverse:
                        Event.code              = PLAYER_EVENT_REVERSE_FAILURE;
                        break;

                    default:
                        //HAVANA_TRACE("Unexpected event %x\n", PlayerEvent.Code);
                        Event.code              = PLAYER_EVENT_INVALID;
                        //memset (Event, 0, sizeof (struct player_event_s));
                        //return HavanaError;
                }
                //HAVANA_TRACE("Code %x, at 0x%llx\n", Event.code, Event.timestamp);

                if (Event.code != PLAYER_EVENT_INVALID)
                    EventSignalCallback (&Event);
            }
            //}}}  
        }
    }

    OS_SetEvent (&EventSignalThreadTerminated);
    HAVANA_DEBUG ("Terminating\n");
}