Example #1
0
////////////////////////////////////////////////////////////////////////////
///
/// Accumulate incoming data until we have the parseable frame header.
///
/// Accumulate data until we have ::FrameHeaderLength
/// bytes stashed away. At this point there is sufficient data accumulated
/// to determine how many bytes will pass us by before the next frame header
/// is expected.
///
/// \return Collator status code, CollatorNoError indicates success.
///
CollatorStatus_t Collator_PesAudio_c::ReadPartialFrameHeader(void)
{
	CollatorStatus_t Status;
	unsigned int BytesNeeded, BytesToRead, FrameLength;
	CollatorState_t OldCollatorState;
	//
	COLLATOR_DEBUG(">><<\n");
	//
	BytesNeeded = FrameHeaderLength - GotPartialFrameHeaderBytes;
	BytesToRead = min(RemainingElementaryLength, BytesNeeded);
	Status = AccumulateData(BytesToRead, RemainingElementaryData);
	if (Status == CollatorNoError)
	{
		GotPartialFrameHeaderBytes += BytesToRead;
		RemainingElementaryData += BytesToRead;
		RemainingElementaryLength -= BytesToRead;
		COLLATOR_DEBUG("BytesNeeded %d; BytesToRead %d\n", BytesNeeded, BytesToRead);
		if (BytesNeeded == BytesToRead)
		{
			//
			// Woo hoo! We've got the whole header, examine it and change state
			//
			StoredFrameHeader = BufferBase + (AccumulatedDataSize - FrameHeaderLength);
			COLLATOR_DEBUG("Got entire frame header packet\n");
			//report_dump_hex( severity_note, StoredFrameHeader, FrameHeaderLength, 32, 0);
			OldCollatorState = CollatorState;
			Status = DecideCollatorNextStateAndGetLength(&FrameLength);
			if (Status != CollatorNoError)
			{
				COLLATOR_DEBUG("Badly formed frame header; seeking new frame header\n");
				return HandleMissingNextFrameHeader();
			}
			if (FrameLength == 0)
			{
				// The LPCM collator needs to do this in order to get a frame evicted before
				// accumulating data from the PES private data area into the frame. The only
				// way it can do this is by reporting a zero length frame and updating some
				// internal state variables. On the next call it will report a non-zero value
				// (i.e. we won't loop forever accumulating no data).
				COLLATOR_DEBUG("Sub-class reported unlikely (but potentially legitimate) frame length (%d)\n", FrameLength);
			}
			if (FrameLength > MaximumCodedFrameSize)
			{
				COLLATOR_ERROR("Sub-class reported absurd frame length (%d)\n", FrameLength);
				return HandleMissingNextFrameHeader();
			}
			// this is the number of bytes we must absorb before switching state to SeekingFrameEnd.
			// if the value is negative then we've already started absorbing the subsequent frame
			// header.
			FramePayloadRemaining = FrameLength - FrameHeaderLength;
			if (CollatorState == GotCompleteFrame)
			{
				AccumulatedFrameReady = true;
				//
				// update the coded frame parameters using the parameters calculated the
				// last time we saw a frame header.
				//
				CodedFrameParameters->PlaybackTimeValid = NextPlaybackTimeValid;
				CodedFrameParameters->PlaybackTime = NextPlaybackTime;
				CodedFrameParameters->DecodeTimeValid = NextDecodeTimeValid;
				CodedFrameParameters->DecodeTime = NextDecodeTime;
			}
			else if (CollatorState == SkipSubFrame)
			{
				/* discard the accumulated frame header */
				AccumulatedDataSize -= FrameHeaderLength;
			}
			if (CollatorState == GotCompleteFrame || OldCollatorState == GotSynchronized)
			{
				//
				// at this point we have discovered a frame header and need to attach a time to it.
				// we can choose between the normal stamp (the stamp of the current PES packet) or the
				// spanning stamp (the stamp of the previous PES packet). Basically if we have accumulated
				// a greater number of bytes than our current offset into the PES packet then we want to
				// use the spanning time.
				//
				bool WantSpanningTime = GetOffsetIntoPacket() < (int) GotPartialFrameHeaderBytes;
				if (WantSpanningTime && !UseSpanningTime)
				{
					COLLATOR_ERROR("Wanted to take the spanning time but this was not available.");
					WantSpanningTime = false;
				}
				if (WantSpanningTime)
				{
					NextPlaybackTimeValid = SpanningPlaybackTimeValid;
					NextPlaybackTime = SpanningPlaybackTime;
					SpanningPlaybackTimeValid = false;
					NextDecodeTimeValid = SpanningDecodeTimeValid;
					NextDecodeTime = SpanningDecodeTime;
					SpanningDecodeTimeValid = false;
					UseSpanningTime = false;
				}
				else
				{
					NextPlaybackTimeValid = PlaybackTimeValid;
					NextPlaybackTime = PlaybackTime;
					PlaybackTimeValid = false;
					NextDecodeTimeValid = DecodeTimeValid;
					NextDecodeTime = DecodeTime;
					DecodeTimeValid = false;
				}
			}
			// switch states and absorb the packet
			COLLATOR_DEBUG("Discovered frame header (frame length %d bytes)\n", FrameLength);
		}
	}
	else
	{
		COLLATOR_DEBUG("Cannot accumulate data #3 (%d)\n", Status);
	}
	return Status;
}
Example #2
0
////////////////////////////////////////////////////////////////////////////
///
/// Accumulate incoming data until we have the parseable frame header.
///
/// Accumulate data until we have ::FrameHeaderLength
/// bytes stashed away. At this point there is sufficient data accumulated
/// to determine how many bytes will pass us by before the next frame header
/// is expected.
///
/// \return Collator status code, CollatorNoError indicates success.
///
CollatorStatus_t Collator_PesAudio_c::ReadPartialFrameHeader( void )
{
    CollatorStatus_t Status;
    unsigned int BytesNeeded, BytesToRead, FrameLength;
    CollatorState_t OldCollatorState;

    //

    COLLATOR_DEBUG(">><<\n");

    //

    BytesNeeded = FrameHeaderLength - GotPartialFrameHeaderBytes;
    BytesToRead = min( RemainingElementaryLength, BytesNeeded );

    Status = AccumulateData( BytesToRead, RemainingElementaryData );
    if( Status == CollatorNoError )
    {
        GotPartialFrameHeaderBytes += BytesToRead;
        RemainingElementaryData += BytesToRead;
        RemainingElementaryLength -= BytesToRead;

        COLLATOR_DEBUG( "BytesNeeded %d; BytesToRead %d\n", BytesNeeded, BytesToRead );
        if( BytesNeeded == BytesToRead )
        {
            //
            // Woo hoo! We've got the whole header, examine it and change state
            //

            StoredFrameHeader = BufferBase + (AccumulatedDataSize - FrameHeaderLength);

            COLLATOR_DEBUG("Got entire frame header packet\n");
            //report_dump_hex( severity_note, StoredFrameHeader, FrameHeaderLength, 32, 0);

            OldCollatorState = CollatorState;
            Status = DecideCollatorNextStateAndGetLength(&FrameLength);
            if( Status != CollatorNoError )
            {
                COLLATOR_DEBUG( "Badly formed frame header; seeking new frame header\n" );
                return HandleMissingNextFrameHeader();
            }

            FramePayloadRemaining = FrameLength - FrameHeaderLength;

            if ((int)FramePayloadRemaining < 0)
            {
                if (CollatorState == GotCompleteFrame)
                {
                    // accumulate the remainder of the frame before the FrameFlush method...
                    Status = AccumulateData( FrameLength, RemainingElementaryData );
                    if (Status != CollatorNoError )
                    {
                        COLLATOR_DEBUG( "Cannot accumulate data #2 (%d)\n", Status );
                        return Status;
                    }
                    StoredFrameHeader = BufferBase + (AccumulatedDataSize - FrameHeaderLength);
                    RemainingElementaryData += FrameLength;
                    RemainingElementaryLength -= FrameLength;

                    // prepare the next call to ReadFrame by setting the correct FramePayloadRemaining
                    Status = GetSpecificFrameLength(&FrameLength);
                    if (Status != CollatorNoError )
                    {
                        COLLATOR_DEBUG( "Cannot get the specific frame length (%d)\n", Status );
                        return Status;
                    }

                    FramePayloadRemaining = FrameLength - FrameHeaderLength;
                }
                else
                {
                    // specific case: reading the header only accumulated too much data
                    // so discard the extra data
                    int NbBytesToDiscard = - (int)FramePayloadRemaining;
                    int temp = NbBytesToDiscard - BytesToRead;

                    AccumulatedDataSize -= NbBytesToDiscard;
                    GotPartialFrameHeaderBytes = (temp > 0)?temp:0;
                    NbBytesToDiscard = min((unsigned int) NbBytesToDiscard, BytesToRead);
                    RemainingElementaryData -= NbBytesToDiscard;
                    RemainingElementaryLength += NbBytesToDiscard;
                }
            }

            if (CollatorState == GotCompleteFrame)
            {
                AccumulatedFrameReady = true;

                //
                // update the coded frame parameters using the parameters calculated the
                // last time we saw a frame header.
                //
                CodedFrameParameters->PlaybackTimeValid = NextPlaybackTimeValid;
                CodedFrameParameters->PlaybackTime = NextPlaybackTime;
                CodedFrameParameters->DecodeTimeValid = NextDecodeTimeValid;
                CodedFrameParameters->DecodeTime = NextDecodeTime;
            }
            else if (CollatorState == SkipSubFrame)
            {
                /* discard the accumulated frame header */
                AccumulatedDataSize -= FrameHeaderLength;
            }

            if (CollatorState == GotCompleteFrame || OldCollatorState == GotSynchronized)
            {
                //
                // at this point we have discovered a frame header and need to attach a time to it.
                // we can choose between the normal stamp (the stamp of the current PES packet) or the
                // spanning stamp (the stamp of the previous PES packet). Basically if we have accumulated
                // a greater number of bytes than our current offset into the PES packet then we want to
                // use the spanning time.
                //

                bool WantSpanningTime = GetOffsetIntoPacket() < (int) GotPartialFrameHeaderBytes;

                if( WantSpanningTime && !UseSpanningTime)
                {
                    COLLATOR_ERROR("Wanted to take the spanning time but this was not available.");
                    WantSpanningTime = false;
                }

                if( WantSpanningTime )
                {
                    NextPlaybackTimeValid = SpanningPlaybackTimeValid;
                    NextPlaybackTime	= SpanningPlaybackTime;
                    SpanningPlaybackTimeValid = false;
                    NextDecodeTimeValid	= SpanningDecodeTimeValid;
                    NextDecodeTime	= SpanningDecodeTime;
                    SpanningDecodeTimeValid = false;
                    UseSpanningTime       = false;
                }
                else
                {
                    NextPlaybackTimeValid = PlaybackTimeValid;
                    NextPlaybackTime	= PlaybackTime;
                    PlaybackTimeValid	= false;
                    NextDecodeTimeValid	= DecodeTimeValid;
                    NextDecodeTime	= DecodeTime;
                    DecodeTimeValid	= false;
                }
            }

            // switch states and absorb the packet
            COLLATOR_DEBUG( "Discovered frame header (frame length %d bytes)\n", FrameLength );
        }
    }
    else
    {
        COLLATOR_DEBUG( "Cannot accumulate data #3 (%d)\n", Status );
    }
    return Status;
}