Exemple #1
0
void CDXVADecoderVC1::CopyBitstream(BYTE* pDXVABuffer, BYTE* pBuffer, UINT& nSize)
{
	int		nDummy;

	if ( (*((DWORD*)pBuffer) & 0x00FFFFFF) != 0x00010000)
	{
		// Some splitter have remove startcode (Haali)
		pDXVABuffer[0]=pDXVABuffer[1]=0; pDXVABuffer[2]=1; pDXVABuffer[3]=0x0D;
		pDXVABuffer	+=4;
		// Copy bitstream buffer, with zero padding (buffer is rounded to multiple of 128)
		memcpy (pDXVABuffer, (BYTE*)pBuffer, nSize);
		nSize  +=4;
	}
	else
	{
		BYTE*	pStart;
		UINT	nPacketSize;

		pStart = FindNextStartCode (pBuffer, nSize, nPacketSize);
		if (pStart)
		{
			// Startcode already present
			memcpy (pDXVABuffer, (BYTE*)pStart, nPacketSize);
			nSize = nPacketSize;
		}
	}
	
	nDummy  = 128 - (nSize %128);

	pDXVABuffer += nSize;
	memset (pDXVABuffer, 0, nDummy);
	nSize  += nDummy;
}
Exemple #2
0
void TDXVADecoderVC1::CopyBitstream(BYTE* pDXVABuffer, BYTE* pBuffer, UINT& nSize)
{
    int nDummy;

    if (m_PictureParams.bSecondField) {
        memcpy(pDXVABuffer, (BYTE*)pBuffer, nSize);
    } else {
        if ((*((DWORD*)pBuffer) & 0x00FFFFFF) != 0x00010000) {
            if (m_pCodec->avctx->codec_id == AV_CODEC_ID_WMV3) {
                memcpy(pDXVABuffer, (BYTE*)pBuffer, nSize);
            } else { // Some splitter have remove startcode (Haali)
                pDXVABuffer[0] = pDXVABuffer[1] = 0;
                pDXVABuffer[2] = 1;
                pDXVABuffer[3] = 0x0D;
                pDXVABuffer += 4;
                memcpy(pDXVABuffer, (BYTE*)pBuffer, nSize);
                nSize  += 4;
            }
        } else {
            BYTE*   pStart;
            UINT    nPacketSize;

            pStart = FindNextStartCode(pBuffer, nSize, nPacketSize);
            if (pStart) {
                // Startcode already present
                memcpy(pDXVABuffer, (BYTE*)pStart, nPacketSize);
                nSize = nPacketSize;
            }
        }
    }

    // Copy bitstream buffer, with zero padding (buffer is rounded to multiple of 128)
    nDummy  = 128 - (nSize % 128);

    pDXVABuffer += nSize;
    memset(pDXVABuffer, 0, nDummy);
    nSize  += nDummy;
}
////////////////////////////////////////////////////////////////////////////
///
/// Scan the input until an appropriate PES start code is found.
///
/// Scans any Collator_Pes_c::RemainingData searching for a PES start code.
/// The configuration for this comes from Collator_Base_c::Configuration and
/// is this means that only the interesting (e.g. PES audio packets) start
/// codes will be detected.
///
/// \return Collator status code, CollatorNoError indicates success.
///
CollatorStatus_t Collator_PesAudio_c::SearchForPesHeader(void)
{
	CollatorStatus_t Status;
	unsigned int CodeOffset;
//
	//
	// If there are any trailing start codes handle those.
	//
	while (TrailingStartCodeBytes && RemainingLength)
	{
		if (TrailingStartCodeBytes == 3)
		{
			// We've got the 0, 0, 1 so if the code is *not* in the ignore range then we've got one
			unsigned char SpecificCode = RemainingData[0];
			if (!inrange(SpecificCode, Configuration.IgnoreCodesRangeStart,
					Configuration.IgnoreCodesRangeEnd))
			{
				COLLATOR_DEBUG("Found a trailing startcode 00, 00, 01, %x\n", SpecificCode);
				// Consume the specific start code
				RemainingData++;
				RemainingLength--;
				// Switch state (and reflect the data we are about to accumulate)
				SeekingPesHeader = false;
				GotPartialPesHeader = true;
				//assert( AccumulatedDataSize == 0 );
				GotPartialPesHeaderBytes = 4;
				// There are now no trailing start code bytes
				TrailingStartCodeBytes = 0;
				// Finally, accumulate the data (by reconstructing it)
				unsigned char StartCode[4] = { 0, 0, 1, SpecificCode };
				Status = AccumulateData(4, StartCode);
				if (Status != CollatorNoError)
					COLLATOR_DEBUG("Cannot accumulate data #5 (%d)\n", Status);
				return Status;
			}
			// Nope, that's not a suitable start code.
			COLLATOR_DEBUG("Trailing start code 00, 00, 01, %x was in the ignore range\n", SpecificCode);
			TrailingStartCodeBytes = 0;
			break;
		}
		else if (TrailingStartCodeBytes == 2)
		{
			// Got two zeros, a one gets us ready to read the code.
			if (RemainingData[0] == 1)
			{
				COLLATOR_DEBUG("Trailing start code looks good (found 00, 00; got 01)\n");
				TrailingStartCodeBytes++;
				RemainingData++;
				RemainingLength--;
				continue;
			}
			// Got two zeros, another zero still leaves us with two zeros.
			if (RemainingData[0] == 0)
			{
				COLLATOR_DEBUG("Trailing start code looks OK (found 00, 00; got 00)\n");
				RemainingData++;
				RemainingLength--;
				continue;
			}
			// Nope, that's not a suitable start code.
			COLLATOR_DEBUG("Trailing 00, 00 was not part of a start code\n");
			TrailingStartCodeBytes = 0;
			break;
		}
		else if (TrailingStartCodeBytes == 1)
		{
			// Got one zero, another zero gives us two (duh).
			if (RemainingData[0] == 0)
			{
				COLLATOR_DEBUG("Trailing start code looks good (found 00; got 00)\n");
				RemainingData++;
				RemainingLength--;
				continue;
			}
			// Nope, that's not a suitable start code.
			COLLATOR_DEBUG("Trailing 00 was not part of a start code\n");
			TrailingStartCodeBytes = 0;
			break;
		}
		else
		{
			COLLATOR_ERROR("TrailingStartCodeBytes has illegal value: %d\n", TrailingStartCodeBytes);
			TrailingStartCodeBytes = 0;
			return CollatorError;
		}
	}
	if (RemainingLength == 0)
	{
		return CollatorNoError;
	}
	//assert(TrailingStartCodeBytes == 0);
//
	Status = FindNextStartCode(&CodeOffset);
	if (Status == CollatorNoError)
	{
		COLLATOR_DEBUG("Locked to PES packet boundaries\n");
		// discard any data leading up to the start code
		RemainingData += CodeOffset;
		RemainingLength -= CodeOffset;
		// switch state
		SeekingPesHeader = false;
		GotPartialPesHeader = true;
		GotPartialPesHeaderBytes = 0;
	}
	else
	{
		// examine the end of the buffer to determine if there is a (potential) trailing start code
		//assert( RemainingLength >= 1 );
		if (RemainingData[RemainingLength - 1] < 1)
		{
			unsigned char LastBytes[3];
			LastBytes[0] = (RemainingLength >= 3 ? RemainingData[RemainingLength - 3] : 0xff);
			LastBytes[1] = (RemainingLength >= 2 ? RemainingData[RemainingLength - 2] : 0xff);
			LastBytes[2] = RemainingData[RemainingLength - 1];
			if (LastBytes[0] == 0 && LastBytes[1] == 0 && LastBytes[2] == 1)
			{
				TrailingStartCodeBytes = 3;
			}
			else if (LastBytes[1] == 0 && LastBytes[2] == 0)
			{
				TrailingStartCodeBytes = 2;
			}
			else if (LastBytes[2] == 0)
			{
				TrailingStartCodeBytes = 1;
			}
		}
		COLLATOR_DEBUG("Discarded %d bytes while searching for PES header (%d might be start code)\n",
			       RemainingLength, TrailingStartCodeBytes);
		RemainingLength = 0;
	}
//
	return CollatorNoError;
}
//}}}
//{{{ Input
////////////////////////////////////////////////////////////////////////////
///
/// Extract Frame length from Pes Private Data area if present.
///
/// \return Collator status code, CollatorNoError indicates success.
///
CollatorStatus_t Collator_PesVideoMjpeg_c::Input(PlayerInputDescriptor_t *Input,
												 unsigned int DataLength,
												 void *Data,
												 bool NonBlocking,
												 unsigned int *DataLengthRemaining)
{
	CollatorStatus_t Status = CollatorNoError;
	unsigned char *DataBlock = (unsigned char *)Data;
	unsigned char *PesHeader;
	unsigned int PesLength;
	unsigned int PayloadLength;
	unsigned int Offset;
	unsigned int CodeOffset;
	unsigned int Code;
	AssertComponentState("Collator_PacketPes_c::Input", ComponentRunning);
	COLLATOR_ASSERT(!NonBlocking);
	InputEntry(Input, DataLength, Data, NonBlocking);
	Offset = 0;
	RemainingData = (unsigned char *)Data;
	RemainingLength = DataLength;
	TerminationFlagIsSet = false;
	Offset = 0;
	while (Offset < DataLength)
	{
		// Read the length of the payload
		PesHeader = DataBlock + Offset;
		PesLength = (PesHeader[4] << 8) + PesHeader[5];
		if (PesLength != 0)
			PayloadLength = PesLength - PesHeader[8] - 3;
		else
			PayloadLength = 0;
		COLLATOR_DEBUG("DataLength %d, PesLength %d; PayloadLength %d, Offset %d\n", DataLength, PesLength, PayloadLength, Offset);
		Offset += PesLength + 6; // PES packet is PesLength + 6 bytes long
		Bits.SetPointer(PesHeader + 9); // Set bits pointer ready to process optional fields
		if ((PesHeader[7] & 0x80) == 0x80) // PTS present?
			//{{{ read PTS
		{
			Bits.FlushUnseen(4);
			PlaybackTime = (unsigned long long)(Bits.Get(3)) << 30;
			Bits.FlushUnseen(1);
			PlaybackTime |= Bits.Get(15) << 15;
			Bits.FlushUnseen(1);
			PlaybackTime |= Bits.Get(15);
			Bits.FlushUnseen(1);
			PlaybackTimeValid = true;
			COLLATOR_DEBUG("PTS %llu.\n", PlaybackTime);
		}
		//}}}
		if ((PesHeader[7] & 0xC0) == 0xC0) // DTS present?
			//{{{ read DTS
		{
			Bits.FlushUnseen(4);
			DecodeTime = (unsigned long long)(Bits.Get(3)) << 30;
			Bits.FlushUnseen(1);
			DecodeTime |= Bits.Get(15) << 15;
			Bits.FlushUnseen(1);
			DecodeTime |= Bits.Get(15);
			Bits.FlushUnseen(1);
			DecodeTimeValid = true;
		}
		//}}}
		else if ((PesHeader[7] & 0xC0) == 0x40)
		{
			COLLATOR_ERROR("Malformed pes header contains DTS without PTS.\n");
			DiscardAccumulatedData(); // throw away previous frame as incomplete
			InputExit();
			return CollatorError;
		}
		RemainingData = PesHeader + (PesLength + 6 - PayloadLength);
		RemainingLength = PayloadLength;
		while (RemainingLength > 0)
		{
			Status = FindNextStartCode(&CodeOffset);
			if (Status != CollatorNoError) // Error indicates no start code found
			{
				Status = AccumulateData(RemainingLength, RemainingData);
				if (Status != CollatorNoError)
					DiscardAccumulatedData();
				RemainingLength = 0;
				break;
			}
			// Got one accumulate up to and including it
			Status = AccumulateData(CodeOffset + 2, RemainingData);
			if (Status != CollatorNoError)
			{
				DiscardAccumulatedData();
				break;
			}
			Code = RemainingData[CodeOffset + 1];
			RemainingLength -= CodeOffset + 2;
			RemainingData += CodeOffset + 2;
			// Is it a block terminate code
			if ((Code == Configuration.BlockTerminateCode) && (AccumulatedDataSize > 2))
			{
				AccumulatedDataSize -= 2;
				Status = InternalFrameFlush((Configuration.StreamTerminateFlushesFrame && (Code == Configuration.StreamTerminationCode)));
				if (Status != CollatorNoError)
					break;
				BufferBase[0] = 0xff;
				BufferBase[1] = Code;
				AccumulatedDataSize = 2;
			}
			// Accumulate the start code
			Status = AccumulateStartCode(PackStartCode(AccumulatedDataSize - 2, Code));
			if (Status != CollatorNoError)
			{
				DiscardAccumulatedData();
				InputExit();
				return Status;
			}
		}
	}
	InputExit();
	return CollatorNoError;
}