size_t StreamProcessor::ProcessPacketWithPayload(StreamProcessor &p, DataVector::iterator curr, DataVector::iterator bufferEnd)
	{
		OVR_CAPTURE_STATIC_ASSERT(PacketType::s_hasPayload == true);

		PacketType                           packet      = {0};
		typename PacketType::PayloadSizeType payloadSize = 0;

		// Check to see if we have enough room for the packet...
		if(sizeof(packet) > (size_t)std::distance(curr, bufferEnd))
			return 0;

		// Load the packet...
		memcpy(&packet, &*curr, sizeof(packet));
		curr += sizeof(packet);

		// Check to see if we have enough room for the payload header...
		if(sizeof(payloadSize) > (size_t)std::distance(curr, bufferEnd))
			return 0;

		// Load the payload header...
		memcpy(&payloadSize, &*curr, sizeof(payloadSize));
		curr += sizeof(payloadSize);

		// Check to see if we have enough room for the payload...
		if(((DataVector::difference_type)payloadSize) > std::distance(curr, bufferEnd))
			return 0;

		void *payloadUnaligned = &*curr;
		void *payloadAligned   = NULL;
		if(payloadSize > 0)
		{
			if(IsAligned(payloadUnaligned, PacketType::s_payloadAlignment))
			{
				// avoid re-allocation+copy unless necessary...
				payloadAligned = payloadUnaligned;
			}
			else
			{
				// TODO: reusable scratch memory blob...
				payloadAligned = malloc(payloadSize);
				memcpy(payloadAligned, payloadUnaligned, payloadSize);
			}
		}

		// Dispatch to callback...
		p.DispatchPacket(packet, payloadAligned, (size_t)payloadSize);

		if(payloadAligned && payloadAligned != payloadUnaligned)
		{
			free(payloadAligned);
		}

		// Return the total size of the packet, including the header...
		return sizeof(PacketHeader) + sizeof(packet) + sizeof(payloadSize) + payloadSize;
	}
	size_t StreamProcessor::ProcessPacket(StreamProcessor &p, DataVector::iterator curr, DataVector::iterator bufferEnd)
	{
		OVR_CAPTURE_STATIC_ASSERT(PacketType::s_hasPayload == false);

		PacketType packet = {0};

		// Check to see if we have enough room for the packet...
		if(sizeof(packet) > (size_t)std::distance(curr, bufferEnd))
			return 0;

		// Load the packet...
		memcpy(&packet, &*curr, sizeof(packet));

		// Dispatch to callback...
		p.DispatchPacket(packet);

		// Return the total size of the packet, including the header...
		return sizeof(PacketHeader) + sizeof(packet);
	}
    AsyncStream::AsyncStream(void)
    {
        m_bufferLock  = 0;

    #if defined(OVR_CAPTURE_POSIX)
        OVR_CAPTURE_STATIC_ASSERT(sizeof(pid_t) <= sizeof(UInt32));
        union
        {
            UInt32 i;
            pid_t  t;
        };
        i = 0;
        t = gettid();
        m_threadID = i;
    #elif defined(OVR_CAPTURE_WINDOWS)
        m_threadID = static_cast<UInt32>(GetCurrentThreadId());
    #else
        #error UNKNOWN PLATFORM!
    #endif

        m_cacheBegin  = (UInt8*)malloc(s_bufferSize);
        m_cacheTail   = m_cacheBegin;
        m_cacheEnd    = m_cacheBegin + s_bufferSize;

        m_flushBegin  = (UInt8*)malloc(s_bufferSize);
        m_flushTail   = m_flushBegin;
        m_flushEnd    = m_flushBegin + s_bufferSize;

        // Make sure we are open by default... we don't close until we fill the buffer...
        m_gate.Open();

        // when we are finally initialized... add ourselves to the linked list...
        g_listlock.Lock();
        m_next = s_head;
        s_head = this;
        g_listlock.Unlock();

        // Try and acquire thread name...
        SendThreadName();
    }