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; }
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; }