virtual bool SplitDataForStreaming(const TArray<uint8>& SrcBuffer, TArray<TArray<uint8>>& OutBuffers) const override
	{
		// 16K chunks - don't really have an idea of what's best for loading from disc yet
		const int32 kMaxChunkSizeBytes = 16384;
		if (SrcBuffer.Num() == 0)
		{
			return false;
		}

		uint32 ReadOffset = 0;
		uint32 WriteOffset = 0;
		uint16 ProcessedFrames = 0;
		const uint8* LockedSrc = SrcBuffer.GetData();

		// Read Identifier, True Sample Count, Number of channels and Frames to Encode first
		if (FCStringAnsi::Strcmp((char*)LockedSrc, OPUS_ID_STRING) != 0)
		{
			return false;
		}
		ReadOffset += FCStringAnsi::Strlen(OPUS_ID_STRING) + 1;
		uint16 SampleRate = *((uint16*)(LockedSrc + ReadOffset));
		ReadOffset += sizeof(uint16);
		uint32 TrueSampleCount = *((uint32*)(LockedSrc + ReadOffset));
		ReadOffset += sizeof(uint32);
		uint8 NumChannels = *(LockedSrc + ReadOffset);
		ReadOffset += sizeof(uint8);
		uint16 SerializedFrames = *((uint16*)(LockedSrc + ReadOffset));
		ReadOffset += sizeof(uint16);

		// Should always be able to store basic info in a single chunk
		check(ReadOffset - WriteOffset < kMaxChunkSizeBytes)

		while (ProcessedFrames < SerializedFrames)
		{
			uint16 FrameSize = *((uint16*)(LockedSrc + ReadOffset));

			if ( (ReadOffset + sizeof(uint16) + FrameSize) - WriteOffset >= kMaxChunkSizeBytes)
			{
				WriteOffset += AddDataChunk(OutBuffers, LockedSrc + WriteOffset, ReadOffset - WriteOffset);
			}

			ReadOffset += sizeof(uint16) + FrameSize;
			ProcessedFrames++;
		}
		if (WriteOffset < ReadOffset)
		{
			WriteOffset += AddDataChunk(OutBuffers, LockedSrc + WriteOffset, ReadOffset - WriteOffset);
		}

		return true;
	}
bool CTXDescriptor::SetupHeaders(ULONG ParsedHeadersLength)
{
    m_CurrVirtioSGLEntry = 0;

    if (m_Headers.VlanHeader()->TCI == 0)
    {
        if (m_AnyLayout)
        {
            return AddDataChunk(m_Headers.VirtioHeaderPA(), m_Headers.VirtioHeaderLength() +
                                ParsedHeadersLength);
        }
        else
        {
            return AddDataChunk(m_Headers.VirtioHeaderPA(), m_Headers.VirtioHeaderLength()) &&
                   AddDataChunk(m_Headers.EthHeaderPA(), ParsedHeadersLength);
        }

    }
    else
    {
        NETKVM_ASSERT(ParsedHeadersLength >= ETH_HEADER_SIZE);

        if (!AddDataChunk(m_Headers.VirtioHeaderPA(), m_Headers.VirtioHeaderLength()) ||
            !AddDataChunk(m_Headers.EthHeaderPA(), ETH_HEADER_SIZE) ||
            !AddDataChunk(m_Headers.VlanHeaderPA(), ETH_PRIORITY_HEADER_SIZE))
        {
            return false;
        }

        if (ParsedHeadersLength > ETH_HEADER_SIZE)
        {
            return AddDataChunk(m_Headers.IPHeadersPA(), ParsedHeadersLength - ETH_HEADER_SIZE);
        }

        return true;
    }
}