示例#1
0
			inline void isend(Buffer_t& buf,const int dest)
			{
				byte* addr = buf.address();
				size_t len = buf.length();
				if(outgoingBuf[dest]){//not NULL
					if(!underlying.testSend(dest)){//busy!
						packet_t pkt(addr, len);
						outgoingQueues[dest].put(pkt);
						return;
					}
					pool.put_address(outgoingBuf[dest]);
				} else {
					nActiveSending++;
				}
			
				if(outgoingQueues[dest].empty()){//bypass and send imediately
					outgoingBuf[dest] = addr;
					isend_internal(addr, len, dest);
				} else {
					packet_t pkt(addr, len);
					outgoingQueues[dest].put(pkt);
					const packet_t pkt1 = outgoingQueues[dest].get();
					isend_internal(pkt1.first, pkt1.second, dest);
					outgoingBuf[dest] = pkt1.first;
				}
			}
//}}}  
//{{{  InjectData
HavanaStatus_t HavanaDemux_c::InjectData       (const unsigned char*            Data,
                                                unsigned int                    DataLength)
{
    Buffer_t                    Buffer;
    PlayerInputDescriptor_t*    InputDescriptor;

    //OS_LockMutex (&InputLock);
    Player->GetInjectBuffer (&Buffer);
    Buffer->ObtainMetaDataReference (Player->MetaDataInputDescriptorType, (void**)&InputDescriptor);

    InputDescriptor->MuxType                    = MuxTypeTransportStream;
    InputDescriptor->DemultiplexorContext       = DemuxContext;

    InputDescriptor->PlaybackTimeValid          = false;
    InputDescriptor->DecodeTimeValid            = false;
    InputDescriptor->DataSpecificFlags          = 0;

    Buffer->RegisterDataReference (DataLength, (void*)Data);
    Buffer->SetUsedDataSize (DataLength);

    Player->InjectData (PlayerPlayback, Buffer);
    //OS_UnLockMutex (&InputLock);

    return HavanaNoError;
}
示例#3
0
CodecStatus_t   Codec_DvpVideo_c::ReleaseDecodeBuffer(Buffer_t Buffer)
{
#if 0
	unsigned int Length;
	unsigned char     *Pointer;
	Buffer->ObtainDataReference(&Length, NULL, (void **)(&Pointer), CachedAddress);
	memset(Pointer, 0x10, 0xa8c00);
#endif
	Buffer->DecrementReferenceCount();
	return CodecNoError;
}
示例#4
0
void MultiChain::copyToBuffer(Buffer_t& buf) {
  double n= static_cast<double>(Beads.size());
  buf.add(n);
  buf.add(GrowthDirection);
  buf.add(Middle);
  buf.add(Last);
  buf.add(nPsi);
  buf.add(Age);
  buf.add(GlobalWgt);
  buf.add(GlobalAction.begin(),GlobalAction.end());
  buf.add(UmbrellaWeight.begin(),UmbrellaWeight.end());
  buf.add(GlobalSignWgt.begin(),GlobalSignWgt.end());
  buf.add(RefSign.begin(),RefSign.end());
}
PlayerStatus_t   Player_Generic_c::AccumulateControlMessage(
						Buffer_t                          Buffer,
						PlayerControlStructure_t         *Message,
						unsigned int                     *MessageCount,
						unsigned int                      MessageTableSize,
						PlayerBufferRecord_t             *MessageTable )
{
unsigned int    i;

//

    for( i=0; i<MessageTableSize; i++ )
	if( MessageTable[i].Buffer == NULL )
	{
	    MessageTable[i].Buffer              = Buffer;
	    MessageTable[i].ControlStructure    = Message;
	    (*MessageCount)++;

	    return PlayerNoError;
	}

//

    report( severity_error, "Player_Generic_c::AccumulateControlMessage - Message table full - Implementation constant range error.\n" );
    Buffer->DecrementReferenceCount();

    return PlayerImplementationError;
}
PlayerStatus_t   Player_Generic_c::ProcessControlMessage(
						PlayerStream_t                    Stream,
						Buffer_t                          Buffer,
						PlayerControlStructure_t         *Message )
{
PlayerStatus_t  Status;

//

    switch( Message->Action )
    {
	case ActionInSequenceCall:
		Status  = PerformInSequenceCall( Stream, Message );
		if( Status != PlayerNoError )
		    report( severity_error, "Player_Generic_c::ProcessControlMessage - Failed InSequence call (%08x)\n", Status );

		break;

	default:
		report( severity_error, "Player_Generic_c::ProcessControlMessage - Unhandled control structure - Implementation error.\n" );
		Status  = PlayerImplementationError;
		break;
    }

    Buffer->DecrementReferenceCount();
    return Status;
}
示例#7
0
void MultiChain::copyFromBuffer(Buffer_t& buf) 
{
  int n(Beads.size());
  buf.get(n);
  buf.get(GrowthDirection);
  buf.get(Middle);
  buf.get(Last);
  buf.get(nPsi);
  buf.get(Age);
  buf.get(GlobalWgt);
  buf.get(GlobalAction.begin(),GlobalAction.end());
  buf.get(UmbrellaWeight.begin(),UmbrellaWeight.end());
  for(int i=0; i<GlobalSignWgt.size(); i++) buf.get(GlobalSignWgt[i]);
  for(int i=0; i<RefSign.size(); i++) buf.get(RefSign[i]);
  //buf.get(GlobalSignWgt.begin(),GlobalSignWgt.end());
  //buf.get(RefSign.begin(),RefSign.end());
}
////////////////////////////////////////////////////////////////////////////
///
/// Attach a coded buffer to the deocded buffer
/// In case of transcoding is required, attach also
/// the transcoded buffer to the original coded buffer
///
void Codec_MmeAudioDtshd_c::AttachCodedFrameBuffer(void)
{
	Codec_MmeAudio_c::AttachCodedFrameBuffer();
	if (TranscodeEnable)
	{
		Buffer_t CodedDataBuffer;
		BufferStatus_t Status;
		Status = CurrentDecodeBuffer->ObtainAttachedBufferReference(CodedFrameBufferType, &CodedDataBuffer);
		if (Status != BufferNoError)
		{
			CODEC_ERROR("Could not get the attached coded data buffer (%d)\n", Status);
			return;
		}
		CodedDataBuffer->AttachBuffer(CurrentTranscodeBuffer);
		CurrentTranscodeBuffer->DecrementReferenceCount();
		// the transcoded buffer is now only referenced by its attachement to the coded buffer
	}
}
示例#9
0
double MMError(size_t N,size_t M,
                const Buffer_t& DistBuffer,const Buffer_t& SerialBuffer){
    double TwoNorm=0.0;
    const size_t BlockSide=N/M;
    for(size_t i=0;i<DistBuffer.size();++i){
        for(size_t j=0;j<BlockSide;++j){
            for(size_t k=0;k<BlockSide;++k){
                double Temp=DistBuffer[i][j*BlockSide+k]-
                            SerialBuffer[i][j*BlockSide+k];
               TwoNorm+=Temp*Temp;
            }
        }
    }
    return sqrt(TwoNorm/(double)N*(double)N);
}
示例#10
0
DemultiplexorStatus_t   Demultiplexor_Base_c::Demux(
	PlayerPlayback_t          Playback,
	DemultiplexorContext_t    Context,
	Buffer_t                  Buffer)
{
	PlayerStatus_t                    Status;
	DemultiplexorBaseContext_t        BaseContext = (DemultiplexorBaseContext_t)Context;
//
	Status      = Buffer->ObtainMetaDataReference(Player->MetaDataInputDescriptorType, (void **)(&BaseContext->Descriptor));
	if (Status != PlayerNoError)
	{
		report(severity_error, "Demultiplexor_Base_c::Demux - Unable to obtain the meta data input descriptor.\n");
		return Status;
	}
//
	Status  = Buffer->ObtainDataReference(NULL, &BaseContext->BufferLength, (void **)(&BaseContext->BufferData));
	if (Status != PlayerNoError)
	{
		report(severity_error, "Demultiplexor_Base_c::Demux - unable to obtain data reference.\n");
		return Status;
	}
//
	return DemultiplexorNoError;
}
BufferStatus_t   Buffer_Generic_c::AttachBuffer( Buffer_t	  Buffer )
{
unsigned int	i;

//

    AssertNonZeroReferenceCount( "Buffer_Generic_c::AttachBuffer" );

    OS_LockMutex( &Lock );
    for( i=0; i<MAX_ATTACHED_BUFFERS; i++ )
	if( AttachedBuffers[i] == NULL )
	{
	    AttachedBuffers[i]	= Buffer;
	    OS_UnLockMutex( &Lock );
	    Buffer->IncrementReferenceCount();
	    return BufferNoError;
	}

    report( severity_error, "Buffer_Generic_c::AttachBuffer - Too many buffers attached to this one.\n" );
    OS_UnLockMutex( &Lock );
    return BufferTooManyAttachments;
}
BufferStatus_t   Buffer_Generic_c::DetachBuffer( Buffer_t	  Buffer )
{
unsigned int	i;

//

    AssertNonZeroReferenceCount( "Buffer_Generic_c::DetachBuffer" );

    OS_LockMutex( &Lock );
    for( i=0; i<MAX_ATTACHED_BUFFERS; i++ )
	if( AttachedBuffers[i] == Buffer )
	{
	    AttachedBuffers[i]	= NULL;
	    OS_UnLockMutex( &Lock );
	    Buffer->DecrementReferenceCount( IdentifierAttachedToOtherBuffer );
	    return BufferNoError;
	}

    report( severity_error, "Buffer_Generic_c::DetachBuffer - Attached buffer not found.\n" );
    OS_UnLockMutex( &Lock );
    return BufferAttachmentNotFound;
}
示例#13
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;
}
FrameParserStatus_t   FrameParser_VideoDvp_c::ReadHeaders( void )
{
Buffer_t		 Buffer;
BufferStructure_t	*BufferStructure;
BufferStatus_t		 BufferStatus;
StreamInfo_t		*StreamInfo;   
PlayerSequenceType_t	 SequenceType;

    //
    // Find the stream info structure, and extract the buffer
    //

    StreamInfo	= (StreamInfo_t*)BufferData;
    Buffer	= (Buffer_t)StreamInfo->buffer_class;

    //
    // Switch the ownership of the buffer
    //

    Buffer->TransferOwnership( IdentifierFrameParser );

    //
    // Modify the buffer structure to match the actual capture
    //

    BufferStatus = Buffer->ObtainMetaDataReference( Player->MetaDataBufferStructureType, (void**)&BufferStructure );
    if (BufferStatus != BufferNoError)
    {
	report( severity_error, "FrameParser_VideoDvp_c::RevPlayPurgeDecodeStacks - Unable to access buffer structure parameters %x.\n", BufferStatus);
	return FrameParserError;
    }

    //
    // Fill out appropriate frame and video parameters
    //

    ParsedFrameParameters->NewStreamParameters 			= false;
    ParsedFrameParameters->SizeofStreamParameterStructure 	= sizeof(StreamInfo_t);
    ParsedFrameParameters->StreamParameterStructure		= &StreamInfo;

    ParsedFrameParameters->FirstParsedParametersForOutputFrame 	= true;
    ParsedFrameParameters->FirstParsedParametersAfterInputJump	= false;
    ParsedFrameParameters->SurplusDataInjected			= false;
    ParsedFrameParameters->ContinuousReverseJump		= false;
    ParsedFrameParameters->KeyFrame				= true;
    ParsedFrameParameters->ReferenceFrame			= true;		// Turn off autogeneration of DTS
    ParsedFrameParameters->IndependentFrame			= true;
    ParsedFrameParameters->NumberOfReferenceFrameLists		= 0;
    
    ParsedFrameParameters->NewFrameParameters			= true;
    ParsedVideoParameters->Content.PixelAspectRatio		= Rational_t(StreamInfo->pixel_aspect_ratio.Numerator, StreamInfo->pixel_aspect_ratio.Denominator);

    ParsedVideoParameters->Content.Width			= StreamInfo->width;
    ParsedVideoParameters->Content.Height			= StreamInfo->height;
    ParsedVideoParameters->Content.DisplayWidth			= StreamInfo->width;
    ParsedVideoParameters->Content.DisplayHeight		= StreamInfo->height;
    ParsedVideoParameters->Content.Progressive			= !StreamInfo->interlaced;
    ParsedVideoParameters->Content.FrameRate			= Rational_t(StreamInfo->FrameRateNumerator, StreamInfo->FrameRateDenominator);
    ParsedVideoParameters->Content.OverscanAppropriate 		= 0;
    ParsedVideoParameters->Content.VideoFullRange		= (StreamInfo->VideoFullRange != 0);
    ParsedVideoParameters->Content.ColourMatrixCoefficients	= ((StreamInfo->ColourMode == DVP_COLOUR_MODE_601) ? MatrixCoefficients_ITU_R_BT601 :
								  ((StreamInfo->ColourMode == DVP_COLOUR_MODE_709) ? MatrixCoefficients_ITU_R_BT709 :
														     MatrixCoefficients_Undefined));

    ParsedVideoParameters->InterlacedFrame			= StreamInfo->interlaced;    
    ParsedVideoParameters->DisplayCount[0]			= 1;
    ParsedVideoParameters->DisplayCount[1]			= ParsedVideoParameters->InterlacedFrame ? 1 : 0;
    ParsedVideoParameters->SliceType				= SliceTypeI;
    ParsedVideoParameters->TopFieldFirst			= StreamInfo->top_field_first;
    ParsedVideoParameters->PictureStructure			= StructureFrame;
 
    ParsedVideoParameters->PanScan.Count			= 0;

    FirstDecodeOfFrame						= true;
    FrameToDecode						= true;

    //
    // Do we need to update any of the window sizes
    //

    SequenceType	= (NextDecodeFrameIndex == 0) ? SequenceTypeImmediate : SequenceTypeBeforePlaybackTime;

    if( memcmp( &StreamInfo->InputWindow, &InputWindow, sizeof(DvpRectangle_t) ) != 0 )
    {
	InputWindow	= StreamInfo->InputWindow;

	Player->CallInSequence( Stream, SequenceType, CodedFramePlaybackTime, 
				ManifestorVideoFnSetInputWindow, 
				InputWindow.X, InputWindow.Y, InputWindow.Width, InputWindow.Height );
    }

//

    if( memcmp( &StreamInfo->OutputWindow, &OutputWindow, sizeof(DvpRectangle_t) ) != 0 )
    {
	OutputWindow	= StreamInfo->OutputWindow;

	Player->CallInSequence( Stream, SequenceType, CodedFramePlaybackTime, 
				ManifestorVideoFnSetOutputWindow, 
				OutputWindow.X, OutputWindow.Y, OutputWindow.Width, OutputWindow.Height );
    }

//

    return FrameParserNoError;
}
示例#15
0
CodecStatus_t   Codec_DvpVideo_c::Input(Buffer_t CodedBuffer)
{
	CodecStatus_t            Status;
	unsigned int             CodedDataLength;
	StreamInfo_t            *StreamInfo;
	Buffer_t             MarkerBuffer;
	BufferStructure_t        BufferStructure;
	ParsedFrameParameters_t     *ParsedFrameParameters;
	ParsedVideoParameters_t     *ParsedVideoParameters;
	Buffer_t             CapturedBuffer;
	ParsedVideoParameters_t     *CapturedParsedVideoParameters;
	//
	// Extract the useful coded data information
	//
	Status      = CodedBuffer->ObtainDataReference(NULL, &CodedDataLength, (void **)(&StreamInfo), CachedAddress);
	if (Status != PlayerNoError)
	{
		report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Unable to obtain data reference.\n");
		return Status;
	}
	Status      = CodedBuffer->ObtainMetaDataReference(Player->MetaDataParsedFrameParametersType, (void **)(&ParsedFrameParameters));
	if (Status != PlayerNoError)
	{
		report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Unable to obtain the meta data \"ParsedFrameParameters\".\n");
		return Status;
	}
	Status      = CodedBuffer->ObtainMetaDataReference(Player->MetaDataParsedVideoParametersType, (void**)&ParsedVideoParameters);
	if (Status != PlayerNoError)
	{
		report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Unable to obtain the meta data \"ParsedVideoParameters\".\n");
		return Status;
	}
	//
	// Handle the special case of a marker frame
	//
	if ((CodedDataLength == 0) && !ParsedFrameParameters->NewStreamParameters && !ParsedFrameParameters->NewFrameParameters)
	{
		//
		// Get a marker buffer
		//
		memset(&BufferStructure, 0x00, sizeof(BufferStructure_t));
		BufferStructure.Format  = FormatMarkerFrame;
		Status      = Manifestor->GetDecodeBuffer(&BufferStructure, &MarkerBuffer);
		if (Status != ManifestorNoError)
		{
			report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Failed to get marker decode buffer from manifestor.\n");
			return Status;
		}
		MarkerBuffer->TransferOwnership(IdentifierCodec);
		Status      = MarkerBuffer->AttachMetaData(Player->MetaDataParsedFrameParametersReferenceType, UNSPECIFIED_SIZE, (void *)ParsedFrameParameters);
		if (Status != PlayerNoError)
		{
			report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Unable to attach a reference to \"ParsedFrameParameters\" to the marker buffer.\n");
			return Status;
		}
		MarkerBuffer->AttachBuffer(CodedBuffer);
		//
		// Queue/pass on the buffer
		//
		OutputRing->Insert((uintptr_t)MarkerBuffer);
		return CodecNoError;
	}
	//
	// Attach the coded data fields to the decode/captured buffer
	//
	CapturedBuffer  = (Buffer_t)StreamInfo->buffer_class;
	if (CapturedBuffer == NULL)
	{
		report(severity_fatal, "Codec_DvpVideo_c::Input(DVP) - NULL Buffer\n");
		return CodecNoError;
	}
//
	Status      = CapturedBuffer->ObtainMetaDataReference(Player->MetaDataParsedVideoParametersType, (void**)&CapturedParsedVideoParameters);
	if (Status != PlayerNoError)
	{
		report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Unable to obtain the meta data \"ParsedVideoParameters\" from the captured buffer.\n");
		return Status;
	}
	memcpy(CapturedParsedVideoParameters, ParsedVideoParameters, sizeof(ParsedVideoParameters_t));
//
	Status      = CapturedBuffer->AttachMetaData(Player->MetaDataParsedFrameParametersReferenceType, UNSPECIFIED_SIZE, (void *)ParsedFrameParameters);
	if (Status != BufferNoError)
	{
		report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Failed to attach Frame Parameters\n");
		return Status;
	}
	//
	// Switch the ownership hierarchy, and allow the captured buffer to exist on it's own.
	//
	CapturedBuffer->IncrementReferenceCount();
	Status  = CodedBuffer->DetachBuffer(CapturedBuffer);
	if (Status != BufferNoError)
	{
		report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Failed to detach captured buffer from coded frame buffer\n");
		return Status;
	}
	Status      = CapturedBuffer->AttachBuffer(CodedBuffer);
	if (Status != BufferNoError)
	{
		report(severity_error, "Codec_DvpVideo_c::Input(DVP) - Failed to attach captured buffer to Coded Frame Buffer\n");
		return Status;
	}
	//
	// Pass the captured buffer on
	//
	OutputRing->Insert((uintptr_t)CapturedBuffer);
	return CodecNoError;
}
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 );
}
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();
	}
    }
CodecStatus_t   Codec_MmeVideoAvs_c::FillOutDecodeCommand(       void )
{
    AvsCodecDecodeContext_t*            Context         = (AvsCodecDecodeContext_t *)DecodeContext;
    AvsFrameParameters_t*               Parsed          = (AvsFrameParameters_t *)ParsedFrameParameters->FrameParameterStructure;
    AvsVideoPictureHeader_t*            PictureHeader   = &Parsed->PictureHeader;
    MME_AVSVideoDecodeParams_t*         Param;
    AVS_StartCodecsParam_t*             StartCodes;
    AVS_DecodedBufferAddress_t*         Decode;
    AVS_RefPicListAddress_t*            RefList;

    unsigned int                        Entry;

    CODEC_DEBUG("%s\n", __FUNCTION__);

    // For avs we do not do slice decodes.
    KnownLastSliceInFieldFrame                  = true;

    Param                                       = &Context->DecodeParameters;
    Decode                                      = &Param->DecodedBufferAddr;
    RefList                                     = &Param->RefPicListAddr;
    StartCodes                                  = &Param->StartCodecs;

#if defined (TRANSFORMER_AVSDEC_HD)
    Param->PictureStartAddr_p                   = (AVS_CompressedData_t)(CodedData + PictureHeader->top_field_offset);
#else
    Param->PictureStartAddr_p                   = (AVS_CompressedData_t)CodedData;
#endif
    Param->PictureEndAddr_p                     = (AVS_CompressedData_t)(CodedData + CodedDataLength);

    Decode->Luma_p                              = (AVS_LumaAddress_t)BufferState[CurrentDecodeBufferIndex].BufferLumaPointer;
    Decode->Chroma_p                            = (AVS_ChromaAddress_t)BufferState[CurrentDecodeBufferIndex].BufferChromaPointer;
    if (Player->PolicyValue( Playback, this->Stream, PolicyDecimateDecoderOutput) != PolicyValueDecimateDecoderOutputDisabled)
    {
        Decode->LumaDecimated_p                 = (AVS_LumaAddress_t)BufferState[CurrentDecodeBufferIndex].DecimatedLumaPointer;
        Decode->ChromaDecimated_p               = (AVS_ChromaAddress_t)BufferState[CurrentDecodeBufferIndex].DecimatedChromaPointer;
    }
    else
    {
        Decode->LumaDecimated_p                 = NULL;
        Decode->ChromaDecimated_p               = NULL;
    }

    //{{{  Obtain MBStruct buffer
    #if defined (AVS_MBSTRUCT)
    if (PictureHeader->ReversePlay)
    {
        if (PictureHeader->picture_coding_type != AVS_PICTURE_CODING_TYPE_B)
        {
            // Get the macroblock structure buffer
            Buffer_t                AvsMbStructBuffer;
            unsigned int            Size;
            CodecStatus_t           Status;

            Size            = ((DecodingWidth + 15) / 16) * ((DecodingHeight + 15) / 16) * 6 * sizeof(unsigned int);

            Status  = AvsMbStructPool->GetBuffer (&AvsMbStructBuffer, Size);
            if( Status != BufferNoError )
            {
                CODEC_ERROR ("Failed to get macroblock structure buffer.\n" );
                return Status;
            }

            AvsMbStructBuffer->ObtainDataReference (NULL, NULL, (void **)&Decode->MBStruct_p, PhysicalAddress);

            CurrentDecodeBuffer->AttachBuffer (AvsMbStructBuffer);          // Attach to decode buffer (so it will be freed at the same time)
            AvsMbStructBuffer->DecrementReferenceCount();                   // and release ownership of the buffer to the decode buffer

            // Remember the MBStruct pointer in case we have a second field to follow
            BufferState[CurrentDecodeBufferIndex].BufferMacroblockStructurePointer  = (unsigned char*)Decode->MBStruct_p;
        }
    }
    else
        Decode->MBStruct_p                      = (U32*)AllocatorPhysicalAddress (MbStructMemoryDevice);
    #else
    Decode->MBStruct_p                          = (U32*)AllocatorPhysicalAddress (MbStructMemoryDevice);
    #endif
    //}}}

    //{{{  Initialise decode buffers to bright pink
    #if 0
    unsigned int        LumaSize        = DecodingWidth*DecodingHeight;
    unsigned char*      LumaBuffer;
    unsigned char*      ChromaBuffer;
    static unsigned int Colour;
    CurrentDecodeBuffer->ObtainDataReference( NULL, NULL, (void**)&LumaBuffer, UnCachedAddress);
    ChromaBuffer                        = LumaBuffer+LumaSize;
    memset (LumaBuffer,   0xff, LumaSize);
    memset (ChromaBuffer, Colour++ & 0xff, LumaSize/2);
    #endif
    //}}}

    //{{{  Fillout the reference frame lists
    if (ParsedFrameParameters->NumberOfReferenceFrameLists != 0)
    {
        if (DecodeContext->ReferenceFrameList[0].EntryCount > 0)
        {
            Entry                                                       = DecodeContext->ReferenceFrameList[0].EntryIndicies[0];
            RefList->BackwardRefLuma_p                                  = (AVS_LumaAddress_t)BufferState[Entry].BufferLumaPointer;
            RefList->BackwardRefChroma_p                                = (AVS_ChromaAddress_t)BufferState[Entry].BufferChromaPointer;
            //Param->Picture_structure_bwd                                = (AVS_PicStruct_t)BufferState[i].PictureSyntax);
    #if defined (AVS_MBSTRUCT)
            if (PictureHeader->ReversePlay)
                Decode->MBStruct_p                                      = (U32*)BufferState[Entry].BufferMacroblockStructurePointer;
    #endif
        }
        if( DecodeContext->ReferenceFrameList[0].EntryCount > 1 )
        {
            Entry                                                       = DecodeContext->ReferenceFrameList[0].EntryIndicies[1];
            RefList->ForwardRefLuma_p                                   = (AVS_LumaAddress_t)BufferState[Entry].BufferLumaPointer;
            RefList->ForwardRefChroma_p                                 = (AVS_ChromaAddress_t)BufferState[Entry].BufferChromaPointer;
    #if defined (AVS_MBSTRUCT)
            if ((PictureHeader->ReversePlay) && (PictureHeader->picture_coding_type == AVS_PICTURE_CODING_TYPE_P))
                Decode->MBStruct_p                                      = (U32*)BufferState[Entry].BufferMacroblockStructurePointer;
    #endif
        }
    }
    //}}}

    //{{{  Fill in remaining fields
    Param->Progressive_frame                                            = (AVS_FrameSyntax_t)PictureHeader->progressive_frame;

    Param->MainAuxEnable                                                = AVS_MAINOUT_EN;
    Param->HorizontalDecimationFactor                                   = AVS_HDEC_1;
    Param->VerticalDecimationFactor                                     = AVS_VDEC_1;

    Param->AebrFlag                                                     = 0;
    Param->Picture_structure                                            = (AVS_PicStruct_t)PictureHeader->picture_structure;
    Param->Picture_structure_bwd                                        = (AVS_PicStruct_t)PictureHeader->picture_structure;

    Param->Fixed_picture_qp                                             = (MME_UINT)PictureHeader->fixed_picture_qp;
    Param->Picture_qp                                                   = (MME_UINT)PictureHeader->picture_qp;
    Param->Skip_mode_flag                                               = (AVS_SkipMode_t)PictureHeader->skip_mode_flag;
    Param->Loop_filter_disable                                          = (MME_UINT)PictureHeader->loop_filter_disable;

    Param->alpha_offset                                                 = (S32)PictureHeader->alpha_c_offset;
    Param->beta_offset                                                  = (S32)PictureHeader->beta_offset;

    Param->Picture_ref_flag                                             = (AVS_PicRef_t)PictureHeader->picture_reference_flag;

    Param->tr                                                           = (S32)PictureHeader->tr;
    Param->imgtr_next_P                                                 = (S32)PictureHeader->imgtr_next_P;
    Param->imgtr_last_P                                                 = (S32)PictureHeader->imgtr_last_P;
    Param->imgtr_last_prev_P                                            = (S32)PictureHeader->imgtr_last_prev_P;

    // To do
    Param->field_flag                                                   = (AVS_FieldSyntax_t)0;
    Param->topfield_pos                                                 = (U32)PictureHeader->top_field_offset;
    Param->botfield_pos                                                 = (U32)PictureHeader->bottom_field_offset;

    Param->DecodingMode                                                 = AVS_NORMAL_DECODE;
    Param->AdditionalFlags                                              = (MME_UINT)0;

    Param->FrameType                                                    = (AVS_PictureType_t)PictureHeader->picture_coding_type;
    //}}}
    //{{{  Fill in decimation values if required
    switch (Player->PolicyValue (Playback, this->Stream, PolicyDecimateDecoderOutput))
    {   
        case PolicyValueDecimateDecoderOutputDisabled:
        {
            // Normal Case
            Param->MainAuxEnable                = AVS_MAINOUT_EN;
            Param->HorizontalDecimationFactor   = AVS_HDEC_1;
            Param->VerticalDecimationFactor     = AVS_VDEC_1;
            break;
        }
        case PolicyValueDecimateDecoderOutputHalf:
        {
            Param->MainAuxEnable                = AVS_AUX_MAIN_OUT_EN;
            Param->HorizontalDecimationFactor   = AVS_HDEC_ADVANCED_2;
            if (Param->Progressive_frame)
                Param->VerticalDecimationFactor = AVS_VDEC_ADVANCED_2_PROG;
            else
                Param->VerticalDecimationFactor = AVS_VDEC_ADVANCED_2_INT;
            break;
        }
        case PolicyValueDecimateDecoderOutputQuarter:
        {
            Param->MainAuxEnable                = AVS_AUX_MAIN_OUT_EN;
            Param->HorizontalDecimationFactor   = AVS_HDEC_ADVANCED_4;
            Param->VerticalDecimationFactor     = AVS_VDEC_ADVANCED_2_INT;
            break;
        }
    }
    //}}}

    //{{{  Fill out slice list if HD decode
    #if defined (TRANSFORMER_AVSDEC_HD)
    StartCodes->SliceCount                                              = Parsed->SliceHeaderList.no_slice_headers;
    for (unsigned int i=0; i<StartCodes->SliceCount; i++)
    {
        StartCodes->SliceArray[i].SliceStartAddrCompressedBuffer_p      = (AVS_CompressedData_t)(CodedData + Parsed->SliceHeaderList.slice_array[i].slice_offset);
        StartCodes->SliceArray[i].SliceAddress                          = Parsed->SliceHeaderList.slice_array[i].slice_start_code;
    }
    #endif
    //}}}

    //{{{  Set up raster buffers if SD decode
    #if !defined (TRANSFORMER_AVSDEC_HD)
    {
        // AVS SD uses both raster and Omega 2 buffers so obtain a raster buffer from the pool as well.
        // Pass details to the firmware in the scatterpages
        BufferStatus_t                  Status;
        Buffer_t                        RasterBuffer;
        BufferStructure_t               RasterBufferStructure;
        unsigned char*                  RasterBufferBase;

        Status                                                          = FillOutDecodeBufferRequest (&RasterBufferStructure);
        if (Status != BufferNoError)
        {
            CODEC_ERROR("%s - Failed to fill out a buffer request structure.\n", __FUNCTION__);
            return Status;
        }
        // Override the format so we get one sized for raster rather than macroblock
        RasterBufferStructure.Format                                    = FormatVideo420_PlanarAligned;
        RasterBufferStructure.ComponentBorder[0]                        = 32;
        RasterBufferStructure.ComponentBorder[1]                        = 32;
        // Ask the manifestor for a buffer of the new format
        Status                                                          = Manifestor->GetDecodeBuffer (&RasterBufferStructure, &RasterBuffer);
        if (Status != BufferNoError)
        {
            CODEC_ERROR("%s - Failed to obtain a decode buffer from the manifestor.\n", __FUNCTION__);
            return Status;
        }
        RasterBuffer->ObtainDataReference (NULL, NULL, (void **)&RasterBufferBase, UnCachedAddress);

        //{{{  Fill in details for all buffers
        for (int i = 0; i < AVS_NUM_MME_BUFFERS; i++)
        {
            DecodeContext->MMEBufferList[i]                             = &DecodeContext->MMEBuffers[i];
            DecodeContext->MMEBuffers[i].StructSize                     = sizeof (MME_DataBuffer_t);
            DecodeContext->MMEBuffers[i].UserData_p                     = NULL;
            DecodeContext->MMEBuffers[i].Flags                          = 0;
            DecodeContext->MMEBuffers[i].StreamNumber                   = 0;
            DecodeContext->MMEBuffers[i].NumberOfScatterPages           = 1;
            DecodeContext->MMEBuffers[i].ScatterPages_p                 = &DecodeContext->MMEPages[i];
            DecodeContext->MMEBuffers[i].StartOffset                    = 0;
        }
        //}}}

        // Then overwrite bits specific to other buffers
        DecodeContext->MMEBuffers[AVS_MME_CURRENT_FRAME_BUFFER].ScatterPages_p[0].Page_p        = RasterBufferBase + RasterBufferStructure.ComponentOffset[0];
        DecodeContext->MMEBuffers[AVS_MME_CURRENT_FRAME_BUFFER].TotalSize                       = RasterBufferStructure.Size;

        // Preserve raster buffer pointers for later use as reference frames
        BufferState[CurrentDecodeBufferIndex].BufferRasterPointer                               = RasterBufferBase + RasterBufferStructure.ComponentOffset[0];

        if (ParsedFrameParameters->NumberOfReferenceFrameLists != 0)
        {
            if (DecodeContext->ReferenceFrameList[0].EntryCount > 0)
            {
                Entry                                                                                       = DecodeContext->ReferenceFrameList[0].EntryIndicies[0];
                DecodeContext->MMEBuffers[AVS_MME_BACKWARD_REFERENCE_FRAME_BUFFER].ScatterPages_p[0].Page_p = BufferState[Entry].BufferRasterPointer;
                DecodeContext->MMEBuffers[AVS_MME_BACKWARD_REFERENCE_FRAME_BUFFER].TotalSize                = RasterBufferStructure.Size;
            }
            if (DecodeContext->ReferenceFrameList[0].EntryCount > 1)
            {
                Entry                                                                                       = DecodeContext->ReferenceFrameList[0].EntryIndicies[1];
                DecodeContext->MMEBuffers[AVS_MME_FORWARD_REFERENCE_FRAME_BUFFER].ScatterPages_p[0].Page_p  = BufferState[Entry].BufferRasterPointer;
                DecodeContext->MMEBuffers[AVS_MME_FORWARD_REFERENCE_FRAME_BUFFER].TotalSize                 = RasterBufferStructure.Size;
            }
        }
        //{{{  Initialise remaining scatter page values
        for (int i = 0; i < AVS_NUM_MME_BUFFERS; i++)
        {                                                                   // Only one scatterpage, so size = totalsize
            DecodeContext->MMEBuffers[i].ScatterPages_p[0].Size         = DecodeContext->MMEBuffers[i].TotalSize;
            DecodeContext->MMEBuffers[i].ScatterPages_p[0].BytesUsed    = 0;
            DecodeContext->MMEBuffers[i].ScatterPages_p[0].FlagsIn      = 0;
            DecodeContext->MMEBuffers[i].ScatterPages_p[0].FlagsOut     = 0;
        }
        //}}}

        // Attach planar buffer to decode buffer and let go of it
        CurrentDecodeBuffer->AttachBuffer (RasterBuffer);
        RasterBuffer->DecrementReferenceCount ();

        //{{{  Initialise raster decode buffers to bright pink
        #if 0
        {
            unsigned int        LumaSize        = (DecodingWidth+32)*(DecodingHeight+32);
            unsigned char*      LumaBuffer      = (unsigned char*)DecodeContext->MMEBuffers[AVS_MME_CURRENT_FRAME_BUFFER].ScatterPages_p[0].Page_p;
            unsigned char*      ChromaBuffer    = &LumaBuffer[LumaSize];
            memset (LumaBuffer,   0xff, LumaSize);
            memset (ChromaBuffer, 0xff, LumaSize/2);
        }
        #endif
        //}}}
    }
    #endif
    //}}}

    // Fillout the actual command
    memset( &Context->BaseContext.MMECommand, 0x00, sizeof(MME_Command_t) );

    Context->BaseContext.MMECommand.CmdStatus.AdditionalInfoSize        = sizeof(Context->DecodeStatus);
    Context->BaseContext.MMECommand.CmdStatus.AdditionalInfo_p          = (MME_GenericParams_t)(&Context->DecodeStatus);
    Context->BaseContext.MMECommand.ParamSize                           = sizeof(Context->DecodeParameters);
    Context->BaseContext.MMECommand.Param_p                             = (MME_GenericParams_t)(&Context->DecodeParameters);

#if !defined (TRANSFORMER_AVSDEC_HD)
    DecodeContext->MMECommand.NumberInputBuffers                        = AVS_NUM_MME_INPUT_BUFFERS;
    DecodeContext->MMECommand.NumberOutputBuffers                       = AVS_NUM_MME_OUTPUT_BUFFERS;
    DecodeContext->MMECommand.DataBuffers_p                             = (MME_DataBuffer_t**)DecodeContext->MMEBufferList;
#endif

    return CodecNoError;
}
示例#19
0
////////////////////////////////////////////////////////////////////////////
///
/// Handle losing lock on the frame headers.
///
/// This function is called to handle the data that was spuriously accumulated
/// when the frame header was badly parsed.
///
/// In principle this function is quite simple. We allocate a new accumulation buffer and
/// use the currently accumulated data is the data source to run the elementary stream
/// state machine. There is however a little extra logic to get rid of recursion.
/// Specificially we change the error handling behaviour if this method is re-entered
/// so that there error is reported back to the already executing copy of the method.
///
/// \return Collator status code, CollatorNoError indicates success.
///
CollatorStatus_t Collator_PesAudio_c::HandleMissingNextFrameHeader(void)
{
	CollatorStatus_t Status;
	//
	// Mark the collator as having lost frame lock.
	// Yes! We really do want to do this before the re-entry checks.
	//
	CollatorState = SeekingSyncWord; // we really do want to do this before the re-entry checks
	AccumulatedFrameReady = false;
	//
	// Check for re-entry
	//
	if (AlreadyHandlingMissingNextFrameHeader)
	{
		COLLATOR_DEBUG("Re-entered the error recovery handler, initiating stack unwind\n");
		return CollatorUnwindStack;
	}
	//
	// Check whether the sub-class wants trivial or aggressive error recovery
	//
	if (!ReprocessAccumulatedDataDuringErrorRecovery)
	{
		DiscardAccumulatedData();
		return CollatorNoError;
	}
	//
	// Remember the original elementary stream pointers for when we return to 'normal' processing.
	//
	unsigned char *OldRemainingElementaryOrigin = RemainingElementaryOrigin;
	unsigned char *OldRemainingElementaryData = RemainingElementaryData;
	unsigned int OldRemainingElementaryLength = RemainingElementaryLength;
	//
	// Take ownership of the already accumulated data
	//
	Buffer_t ReprocessingDataBuffer = CodedFrameBuffer;
	unsigned char *ReprocessingData = BufferBase;
	unsigned int ReprocessingDataLength = AccumulatedDataSize;
	ReprocessingDataBuffer->SetUsedDataSize(ReprocessingDataLength);
	Status = ReprocessingDataBuffer->ShrinkBuffer(max(ReprocessingDataLength, 1));
	if (Status != BufferNoError)
	{
		COLLATOR_ERROR("Failed to shrink the reprocessing buffer to size (%08x).\n", Status);
		// not fatal - we're merely wasting memory
	}
	// At the time of writing GetNewBuffer() doesn't check for leaks. This is good because otherwise
	// we wouldn't have transfer the ownership of the ReprocessingDataBuffer by making this call.
	Status = GetNewBuffer();
	if (Status != CollatorNoError)
	{
		COLLATOR_ERROR("Cannot get new buffer during error recovery\n");
		return CollatorError;
	}
	//
	// Remember that we are re-processing the previously accumulated elementary stream
	//
	AlreadyHandlingMissingNextFrameHeader = true;
	//
	// WARNING: From this point on we own the ReprocessingDataBuffer, have set the recursion avoidance
	// marker and may have damaged the RemainingElementaryData pointer. There should be no
	// short-circuit exit paths used after this point otherwise we risk avoiding the clean up
	// at the bottom of the method.
	//
	while (ReprocessingDataLength > 1)
	{
		//
		// Remove the first byte from the recovery buffer (to avoid detecting again the same start code).
		//
		ReprocessingData += 1;
		ReprocessingDataLength -= 1;
		//
		// Search for a start code in the reprocessing data. This allows us to throw away data that we
		// know will never need reprocessing which makes the recursion avoidance code more efficient.
		//
		RemainingElementaryOrigin = ReprocessingData;
		RemainingElementaryData = ReprocessingData;
		RemainingElementaryLength = ReprocessingDataLength;
		int CodeOffset;
		PotentialFrameHeaderLength = 0; // ensure no (now voided) historic data is considered by sub-class
		Status = FindNextSyncWord(&CodeOffset);
		if (Status == CodecNoError)
		{
			COLLATOR_ASSERT(CodeOffset >= 0);
			COLLATOR_DEBUG("Found start code during error recovery (byte %d of %d)\n",
				       CodeOffset, ReprocessingDataLength);
			// We found a start code, snip off all preceding data
			ReprocessingData += CodeOffset;
			ReprocessingDataLength -= CodeOffset;
		}
		else
		{
			// We didn't find a start code, snip off everything except the last few bytes. This
			// final fragment may contain a partial start code so we want to pass if through the
			// elementary stream handler again.
			unsigned FinalBytes = min(ReprocessingDataLength, FrameHeaderLength - 1);
			COLLATOR_DEBUG("Found no start code during error recovery (processing final %d bytes of %d)\n",
				       ReprocessingDataLength, FinalBytes);
			ReprocessingData += ReprocessingDataLength;
			ReprocessingDataLength = FinalBytes;
			ReprocessingData -= ReprocessingDataLength;
		}
		//
		// Process the elementary stream
		//
		Status = HandleElementaryStream(ReprocessingDataLength, ReprocessingData);
		if (CollatorNoError == Status)
		{
			COLLATOR_DEBUG("Error recovery completed, returning to normal processing\n");
			// All data consumed and stored in the subsequent accumulation buffer
			break; // Success will propagate when we return Status
		}
		else if (CollatorUnwindStack == Status)
		{
			COLLATOR_DEBUG("Stack unwound successfully, re-trying error recovery\n");
			// We found a frame header but lost lock again... let's have another go
			AccumulatedDataSize = 0; // make sure no accumulated data is carried round the loop
			continue;
		}
		else
		{
			COLLATOR_ERROR("Error handling elementary stream during error recovery\n");
			break; // Failure will propagate when we return Status
		}
	}
	//
	// Free the buffer we just consumed and restore the original elementary stream pointers
	//
	RemainingElementaryOrigin = OldRemainingElementaryOrigin;
	RemainingElementaryData = OldRemainingElementaryData;
	RemainingElementaryLength = OldRemainingElementaryLength;
	(void) ReprocessingDataBuffer->DecrementReferenceCount(IdentifierCollator);
	AlreadyHandlingMissingNextFrameHeader = false;
	return Status;
}
示例#20
0
PlayerStatus_t Player_Generic_c::InjectData(PlayerPlayback_t Playback,
											Buffer_t Buffer)
{
	unsigned int i;
	unsigned int Length;
	void *Data;
	PlayerInputMuxType_t MuxType;
	PlayerStatus_t Status;
#ifdef __TDT__
	DemultiplexorStatus_t DemuxStatus = NULL;
#endif
	PlayerInputDescriptor_t *Descriptor;
//
	Status = Buffer->ObtainMetaDataReference(MetaDataInputDescriptorType, (void **)(&Descriptor));
	if (Status != PlayerNoError)
	{
		report(severity_error, "Player_Generic_c::InjectData - Unable to obtain the meta data input descriptor.\n");
		return Status;
	}
//
	if (Descriptor->MuxType == MuxTypeUnMuxed)
	{
		//
		// Un muxed data, call the appropriate collator
		//
		Status = Buffer->ObtainDataReference(NULL, &Length, &Data);
		if (Status != PlayerNoError)
		{
			report(severity_error, "Player_Generic_c::InjectData - unable to obtain data reference.\n");
			return Status;
		}
		Status = Descriptor->UnMuxedStream->Collator->Input(Descriptor, Length, Data);
	}
	else
	{
		//
		// Data is muxed - seek a demultiplexor and pass on the call
		//
		for (i = 0; i < DemultiplexorCount; i++)
		{
			Demultiplexors[i]->GetHandledMuxType(&MuxType);
			if (MuxType == Descriptor->MuxType)
				break;
		}
		if (i < DemultiplexorCount)
		{
#ifdef __TDT__
			DemuxStatus = Demultiplexors[i]->Demux(Playback, Descriptor->DemultiplexorContext, Buffer);
#else
			Status = Demultiplexors[i]->Demux(Playback, Descriptor->DemultiplexorContext, Buffer);
#endif
		}
		else
		{
			report(severity_error, "Player_Generic_c::InjectData - No suitable demultiplexor registerred for this MuxType (%d).\n", Descriptor->MuxType);
			Status = PlayerUnknowMuxType;
		}
	}
#ifdef __TDT__
	if (DemuxStatus == DemultiplexorBufferOverflow)
		for (PlayerStream_t Stream = Playback->ListOfStreams; Stream != NULL; Stream = Stream->Next)
			Stream->Collator->DiscardAccumulatedData();
#endif
	//
	// Release the buffer
	//
	Buffer->DecrementReferenceCount(IdentifierGetInjectBuffer);
	return Status;
}
PlayerStatus_t   Player_Generic_c::CallInSequence(
						PlayerStream_t            Stream,
						PlayerSequenceType_t      SequenceType,
						PlayerSequenceValue_t     SequenceValue,
						PlayerComponentFunction_t Fn,
						... )
{
va_list                   List;
BufferStatus_t            Status;
Buffer_t                  ControlStructureBuffer;
PlayerControlStructure_t *ControlStructure;
Ring_t                    DestinationRing;

    //
    // Garner a control structure, fill it in
    //

    Status      = PlayerControlStructurePool->GetBuffer( &ControlStructureBuffer, IdentifierInSequenceCall );
    if( Status != PlayerNoError )
    {
	report( severity_error, "Player_Generic_c::CallInSequence - Failed to get a control structure buffer.\n" );
	return Status;
    }

    ControlStructureBuffer->ObtainDataReference( NULL, NULL, (void **)(&ControlStructure) );

    ControlStructure->Action            = ActionInSequenceCall;
    ControlStructure->SequenceType      = SequenceType;
    ControlStructure->SequenceValue     = SequenceValue;
    ControlStructure->InSequence.Fn     = Fn;

//

    DestinationRing                     = NULL;

    switch( Fn )
    {
	case FrameParserFnSetModuleParameters:
		DestinationRing         = Stream->CollatedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.UnsignedInt        = va_arg( List, unsigned int );
		memcpy( ControlStructure->InSequence.Block, va_arg( List, void * ), ControlStructure->InSequence.UnsignedInt );
		va_end( List );

		break;

//

	case CodecFnOutputPartialDecodeBuffers:
		DestinationRing         = Stream->ParsedFrameRing;
		break;

//

	case CodecFnReleaseReferenceFrame:
		DestinationRing         = Stream->ParsedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.UnsignedInt        = va_arg( List, unsigned int );
		va_end( List );

//report(severity_info, "Requesting a release %d\n", ControlStructure->InSequence.UnsignedInt );

		break;

//

	case CodecFnSetModuleParameters:
		DestinationRing = Stream->ParsedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.UnsignedInt        = va_arg( List, unsigned int );
		memcpy( ControlStructure->InSequence.Block, va_arg( List, void * ), ControlStructure->InSequence.UnsignedInt );
		va_end( List );

		break;

//

	case ManifestorFnSetModuleParameters:
		DestinationRing = Stream->DecodedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.UnsignedInt        = va_arg( List, unsigned int );
		memcpy( ControlStructure->InSequence.Block, va_arg( List, void * ), ControlStructure->InSequence.UnsignedInt );
		va_end( List );

		break;

//

	case ManifestorFnQueueEventSignal:
		DestinationRing = Stream->DecodedFrameRing;

		va_start( List, Fn );
		memcpy( &ControlStructure->InSequence.Event, va_arg( List, PlayerEventRecord_t * ), sizeof(PlayerEventRecord_t) );
		va_end( List );

		break;

//

	case ManifestorVideoFnSetInputWindow:
	case ManifestorVideoFnSetOutputWindow:
		DestinationRing = Stream->DecodedFrameRing;

		va_start( List, Fn );
		{
		    unsigned int *Words	= (unsigned int *)ControlStructure->InSequence.Block;

		    Words[0]		= va_arg( List, unsigned int );
		    Words[1]		= va_arg( List, unsigned int );
		    Words[2]		= va_arg( List, unsigned int );
		    Words[3]		= va_arg( List, unsigned int );
		}
		va_end( List );

		break;

//

	case OutputTimerFnResetTimeMapping:
		DestinationRing = Stream->DecodedFrameRing;
		break;

//

	case OutputTimerFnSetModuleParameters:
		DestinationRing = Stream->DecodedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.UnsignedInt        = va_arg( List, unsigned int );
		memcpy( ControlStructure->InSequence.Block, va_arg( List, void * ), ControlStructure->InSequence.UnsignedInt );
		va_end( List );

		break;

//

	case OSFnSetEventOnManifestation:
		DestinationRing = Stream->DecodedFrameRing;     // This is where manifestation would take place

		va_start( List, Fn );
		ControlStructure->InSequence.Pointer    = (void *)va_arg( List, OS_Event_t * );
		va_end( List );

		break;

//

	case OSFnSetEventOnPostManifestation:
		DestinationRing = Stream->ManifestedBufferRing;

		va_start( List, Fn );
		ControlStructure->InSequence.Pointer    = (void *)va_arg( List, OS_Event_t * );
		va_end( List );

		break;

//

	case PlayerFnSwitchFrameParser:
		DestinationRing = Stream->CollatedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.Pointer    = (void *)va_arg( List, PlayerStream_t );
		va_end( List );

		break;

//

	case PlayerFnSwitchCodec:
		DestinationRing = Stream->ParsedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.Pointer    = (void *)va_arg( List, PlayerStream_t );
		va_end( List );

		break;

//

	case PlayerFnSwitchOutputTimer:
		DestinationRing = Stream->DecodedFrameRing;

		va_start( List, Fn );
		ControlStructure->InSequence.Pointer    = (void *)va_arg( List, PlayerStream_t );
		va_end( List );

		break;

//

	case PlayerFnSwitchComplete:
		DestinationRing = Stream->ManifestedBufferRing;

		va_start( List, Fn );
		ControlStructure->InSequence.Pointer    = (void *)va_arg( List, PlayerStream_t );
		va_end( List );

		break;

//

	default:
		report( severity_error, "Player_Generic_c::CallInSequence - Unsupported function call.\n" );
		ControlStructureBuffer->DecrementReferenceCount( IdentifierInSequenceCall );
		return PlayerNotSupported;
    }

    //
    // Send it to the appropriate process
    //

    DestinationRing->Insert( (unsigned int)ControlStructureBuffer );

//

    return PlayerNoError;
}
示例#22
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;
}
//}}}
//{{{  FillOutSetStreamParametersCommand
// /////////////////////////////////////////////////////////////////////////
//
//      Function to fill out the stream parameters
//      structure for an Rmv mme transformer.
//
CodecStatus_t   Codec_MmeVideoRmv_c::FillOutSetStreamParametersCommand( void )
{
    RmvStreamParameters_t*      Parsed          = (RmvStreamParameters_t*)ParsedFrameParameters->StreamParameterStructure;
    RmvVideoSequence_t*         SequenceHeader  = &Parsed->SequenceHeader;
    unsigned int                MaxWidth;
    unsigned int                MaxHeight;
    RV89Dec_fid_t               FormatId;
    int                         IsRV8           = 1;
    unsigned int                NumRPRSizes;
    unsigned int                i;

    MaxWidth                    = SequenceHeader->MaxWidth;
    MaxHeight                   = SequenceHeader->MaxHeight;

    if ((SequenceHeader->BitstreamVersion == RV9_BITSTREAM_VERSION) &&
        (SequenceHeader->BitstreamMinorVersion == RV9_BITSTREAM_MINOR_VERSION))
    {
        FormatId                = RV89DEC_FID_REALVIDEO30;
        IsRV8                   = 0;
    }
    else if ((SequenceHeader->BitstreamVersion == RV8_BITSTREAM_VERSION) &&
             (SequenceHeader->BitstreamMinorVersion == RV8_BITSTREAM_MINOR_VERSION))
    {
        FormatId                = RV89DEC_FID_REALVIDEO30;
        IsRV8                   = 1;
    }
    else if (SequenceHeader->BitstreamMinorVersion == RV89_RAW_BITSTREAM_MINOR_VERSION)
    {
        FormatId                = RV89DEC_FID_RV89COMBO;
        if (SequenceHeader->BitstreamVersion == RV8_BITSTREAM_VERSION)
            IsRV8               = 1;
    }
    else
    {
        CODEC_ERROR ("Invalid Bitstream versions (%d, %d)\n",
                      SequenceHeader->BitstreamVersion, SequenceHeader->BitstreamMinorVersion);
        return CodecError;
    }
    NumRPRSizes                 = IsRV8 ? SequenceHeader->NumRPRSizes : 0;

#if 0
    if ((MaxWidth    != InitializationParameters.MaxWidth)          ||
        (MaxHeight   != InitializationParameters.MaxHeight)         ||
        (FormatId    != InitializationParameters.StreamFormatIdentifier) ||
        (IsRV8       != InitializationParameters.isRV8)             ||
        (NumRPRSizes != InitializationParameters.NumRPRSizes))
    {
#endif
    InitializationParameters.MaxWidth               = MaxWidth;
    InitializationParameters.MaxHeight              = MaxHeight;
    InitializationParameters.StreamFormatIdentifier = FormatId;
    InitializationParameters.isRV8                  = IsRV8;
    InitializationParameters.NumRPRSizes            = NumRPRSizes;
    for (i=0; i<(NumRPRSizes*2); i+=2)
    {
        InitializationParameters.RPRSize[i]         = SequenceHeader->RPRSize[i];
        InitializationParameters.RPRSize[i+1]       = SequenceHeader->RPRSize[i+1];
    }
    InitializationParameters.pIntraMBInfo           = NULL;

    RestartTransformer      = true;

    return CodecNoError;

}
//}}}
//{{{  FillOutDecodeCommand
// /////////////////////////////////////////////////////////////////////////
//
//      Function to fill out the decode parameters
//      structure for an rmv mme transformer.
//

//#define RV89_INTERFACE_V0_0_4
CodecStatus_t   Codec_MmeVideoRmv_c::FillOutDecodeCommand(       void )
{
    RmvCodecDecodeContext_t*            Context         = (RmvCodecDecodeContext_t*)DecodeContext;
    RmvFrameParameters_t*               Frame           = (RmvFrameParameters_t*)ParsedFrameParameters->FrameParameterStructure;

    RV89Dec_TransformParams_t*          Param;
    RmvVideoSegmentList_t*              SegmentList;
    Buffer_t                            SegmentInfoBuffer;
    RV89Dec_Segment_Info*               SegmentInfo;

    Buffer_t                            RasterBuffer;
    BufferStructure_t                   RasterBufferStructure;
    unsigned char*                      RasterBufferBase;

    CodecStatus_t                       Status;
    unsigned int                        i;

    // For rmv we do not do slice decodes.
    KnownLastSliceInFieldFrame                  = true;

    Param                                       = &Context->DecodeParameters;
    SegmentList                                 = &Frame->SegmentList;

    // Fillout the straight forward command parameters
#if defined (RV89_INTERFACE_V0_0_4)
    Param->InBuffer.pCompressedData             = (unsigned char*)CodedData;
    Param->InBuffer.CompressedDataBufferSize    = CodedDataLength;
#elif defined (SMALL_CIRCULAR_BUFFER)
    // The first two assume a circular buffer arrangement
    Param->InBuffer.pStartPtr                   = (unsigned char*)CodedData;
    Param->InBuffer.pEndPtr                     = Param->InBuffer.pStartPtr + CodedDataLength + 4096;
    Param->InBuffer.PictureOffset               = 0;
    Param->InBuffer.PictureSize                 = CodedDataLength;
#else
    // The first two assume a circular buffer arrangement
    Param->InBuffer.pStartPtr                   = (unsigned char*)0x00;
    Param->InBuffer.pEndPtr                     = (unsigned char*)0xffffffff;
    Param->InBuffer.PictureOffset               = (unsigned int)CodedData;
    Param->InBuffer.PictureSize                 = CodedDataLength;
#endif

    // Get the segment list buffer
    Status                                      = SegmentListPool->GetBuffer (&SegmentInfoBuffer,
                                                                              (sizeof(RV89Dec_Segment_Info))*(SegmentList->NumSegments+1));
    if (Status != BufferNoError)
    {
        CODEC_ERROR ("Failed to get segment info buffer.\n" );
        return Status;
    }

    // Copy segment list
    //Param->InBuffer.NumSegments                 = SegmentList->NumSegments;
    Param->InBuffer.NumSegments                 = SegmentList->NumSegments;
    SegmentInfoBuffer->ObtainDataReference (NULL, NULL, (void**)&SegmentInfo, UnCachedAddress);
    for (i=0; i<SegmentList->NumSegments; i++)
    {
        SegmentInfo[i].is_valid                 = 1;
        SegmentInfo[i].offset                   = SegmentList->Segment[i].Offset;
    }
    SegmentInfo[i].is_valid                     = 0;
    SegmentInfo[i].offset                       = CodedDataLength;

    // Tell far side how to find list
    SegmentInfoBuffer->ObtainDataReference (NULL, NULL, (void **)&Param->InBuffer.pSegmentInfo, PhysicalAddress);

    // Attach allocated segment list buffer to decode context and let go of it
    DecodeContextBuffer->AttachBuffer (SegmentInfoBuffer);
    SegmentInfoBuffer->DecrementReferenceCount ();

    Status                                      = FillOutDecodeBufferRequest (&RasterBufferStructure);
    if (Status != BufferNoError)
    {
        report (severity_error, "Codec_MmeVideoRmv_c::FillOutDecodeCommand - Failed to fill out a buffer request structure.\n");
        return Status;
    }
    // Override the format so we get one sized for raster rather than macroblock
    RasterBufferStructure.Format                = FormatVideo420_Planar;
    RasterBufferStructure.ComponentBorder[0]    = 16;
    RasterBufferStructure.ComponentBorder[1]    = 16;
    // Ask the manifestor for a buffer of the new format
    Status                                      = Manifestor->GetDecodeBuffer (&RasterBufferStructure, &RasterBuffer);
    if (Status != BufferNoError)
    {
        report (severity_error, "Codec_MmeVideoRmv_c::FillOutDecodeCommand - Failed to obtain a decode buffer from the manifestor.\n");
        return Status;
    }
    RasterBuffer->ObtainDataReference (NULL, NULL, (void **)&RasterBufferBase, PhysicalAddress);

    // Fill in all buffer luma and chroma pointers
    Param->Outbuffer.pLuma                      = (RV89Dec_LumaAddress_t)BufferState[CurrentDecodeBufferIndex].BufferLumaPointer;
    Param->Outbuffer.pChroma                    = (RV89Dec_ChromaAddress_t)BufferState[CurrentDecodeBufferIndex].BufferChromaPointer;

#if defined (RV89_INTERFACE_V0_0_4)
    // Move pointer to first byte inside border
    RasterBufferStructure.ComponentOffset[0]    = RasterBufferStructure.Dimension[0] * 16 + 16;
    RasterBufferStructure.ComponentOffset[1]   += RasterBufferStructure.Dimension[0] * 8 + 8;
#endif

#if 0
    // Initialise decode buffers to bright pink
    unsigned char*      LumaBuffer;
    unsigned char*      ChromaBuffer;
    unsigned int        LumaSize        = InitializationParameters.MaxWidth*InitializationParameters.MaxHeight;
    CurrentDecodeBuffer->ObtainDataReference( NULL, NULL, (void**)&LumaBuffer, UnCachedAddress);
    ChromaBuffer                        = LumaBuffer+LumaSize;
    memset (LumaBuffer,   0x00, LumaSize);
    memset (ChromaBuffer, 0x80, LumaSize/2);
    RasterBuffer->ObtainDataReference( NULL, NULL, (void**)&LumaBuffer, UnCachedAddress);
    LumaSize                            = RasterBufferStructure.ComponentOffset[1];
    ChromaBuffer                        = LumaBuffer+LumaSize;
    memset (LumaBuffer,   0xff, LumaSize);
    memset (ChromaBuffer, 0xff, LumaSize/2);
#endif

    Param->CurrDecFrame.pLuma                   = (RV89Dec_LumaAddress_t)(RasterBufferBase + RasterBufferStructure.ComponentOffset[0]);
    Param->CurrDecFrame.pChroma                 = (RV89Dec_ChromaAddress_t)(RasterBufferBase + RasterBufferStructure.ComponentOffset[1]);

    // Attach planar buffer to decode buffer and let go of it
    CurrentDecodeBuffer->AttachBuffer (RasterBuffer);
    RasterBuffer->DecrementReferenceCount ();

    // Preserve raster buffer pointers for later use as reference frames
    BufferState[CurrentDecodeBufferIndex].BufferRasterPointer                   = Param->CurrDecFrame.pLuma;
    BufferState[CurrentDecodeBufferIndex].BufferMacroblockStructurePointer      = Param->CurrDecFrame.pChroma;

    // Fillout the reference frame lists - default to self if not present
    if ((ParsedFrameParameters->NumberOfReferenceFrameLists == 0) || (DecodeContext->ReferenceFrameList[0].EntryCount == 0))
    {
        Param->PrevRefFrame.pLuma               = Param->CurrDecFrame.pLuma;
        Param->PrevRefFrame.pChroma             = Param->CurrDecFrame.pChroma;
        Param->PrevMinusOneRefFrame.pLuma       = Param->CurrDecFrame.pLuma;
        Param->PrevMinusOneRefFrame.pChroma     = Param->CurrDecFrame.pChroma;
    }
    else
    {
        i                                       = DecodeContext->ReferenceFrameList[0].EntryIndicies[0];
        Param->PrevRefFrame.pLuma               = (RV89Dec_LumaAddress_t)BufferState[i].BufferRasterPointer;
        Param->PrevRefFrame.pChroma             = (RV89Dec_ChromaAddress_t)BufferState[i].BufferMacroblockStructurePointer;
        i                                       = DecodeContext->ReferenceFrameList[0].EntryIndicies[1];
        Param->PrevMinusOneRefFrame.pLuma       = (RV89Dec_LumaAddress_t)BufferState[i].BufferRasterPointer;
        Param->PrevMinusOneRefFrame.pChroma     = (RV89Dec_ChromaAddress_t)BufferState[i].BufferMacroblockStructurePointer;
    }

    //{{{  DEBUG
    {

        report( severity_info,  "Codec Picture No %d, Picture type %d\n", PictureNo++, Frame->PictureHeader.PictureCodingType);
    #if 0
        report( severity_info,  "Codec Picture No %d, Picture type %d\n", PictureNo++, Frame->PictureHeader.PictureCodingType);
        report( severity_info,  "      InBuffer.pCompressedData             = %08x\n", Param->InBuffer.pCompressedData);
        report( severity_info,  "      InBuffer.CompressedDataBufferSize    = %d\n",   Param->InBuffer.CompressedDataBufferSize);
        report( severity_info,  "      InBuffer.NumSegments                 = %d\n",   Param->InBuffer.NumSegments);
        report( severity_info,  "      InBuffer.pSegmentInfo                = %08x\n", Param->InBuffer.pSegmentInfo);
        for (i=0; i<Param->InBuffer.NumSegments+1; i++)
        {
            report( severity_info,  "      InBuffer.SegmentInfo[%d]             = %d, %d\n", i, SegmentInfo[i].is_valid, SegmentInfo[i].offset);
        }
        report( severity_info,  "      CurrDecFrame.pLuma                   = %08x\n", Param->CurrDecFrame.pLuma);
        report( severity_info,  "      CurrDecFrame.pChroma                 = %08x\n", Param->CurrDecFrame.pChroma);
        report( severity_info,  "      Outbuffer.pLuma                      = %08x\n", Param->Outbuffer.pLuma);
        report( severity_info,  "      Outbuffer.pChroma                    = %08x\n", Param->Outbuffer.pChroma);
        report( severity_info,  "      PrevRefFrame.pLuma                   = %08x\n", Param->PrevRefFrame.pLuma);
        report( severity_info,  "      PrevRefFrame.pChroma                 = %08x\n", Param->PrevRefFrame.pChroma);
        report( severity_info,  "      PrevMinusOneRefFrame.pLuma           = %08x\n", Param->PrevMinusOneRefFrame.pLuma);
        report( severity_info,  "      PrevMinusOneRefFrame.pChroma         = %08x\n", Param->PrevMinusOneRefFrame.pChroma);
    #endif
    }
    //}}}

    // Fillout the actual command
    memset( &Context->BaseContext.MMECommand, 0x00, sizeof(MME_Command_t) );

    Context->BaseContext.MMECommand.CmdStatus.AdditionalInfoSize    = sizeof(RV89Dec_TransformStatusAdditionalInfo_t);
    Context->BaseContext.MMECommand.CmdStatus.AdditionalInfo_p      = (MME_GenericParams_t)(&Context->DecodeStatus);
    Context->BaseContext.MMECommand.ParamSize                       = sizeof(RV89Dec_TransformParams_t);
    Context->BaseContext.MMECommand.Param_p                         = (MME_GenericParams_t)(&Context->DecodeParameters);

    return CodecNoError;
}
示例#24
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;
}