HoloLens2-Unity-ResearchModeStreamer icon indicating copy to clipboard operation
HoloLens2-Unity-ResearchModeStreamer copied to clipboard

How can I see debug info? (I am tring UDP)

Open sinkers-lan opened this issue 2 years ago • 0 comments

I am now trying to use UDP instead of TCP to send pics to remote python. And now I think I have aready done. But I'm worrying about how to debug. How can I see the debug infomations using OutputDebugStringW when running on Hololens2? Or if I have other efficient way to test my code?

This is my eadapted code VideoCameraStreamer.cpp, part of it is generated by ChatGpt. I hope it may works. If someone can give me some seggustions I would appreciate it:

#include "pch.h"

#define DBG_ENABLE_VERBOSE_LOGGING 0
#define DBG_ENABLE_INFO_LOGGING 1
#define DBG_ENABLE_ERROR_LOGGING 1

using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Media::Capture;
using namespace winrt::Windows::Media::Capture::Frames;
using namespace winrt::Windows::Graphics::Imaging;
using namespace winrt::Windows::Perception::Spatial;
using namespace winrt::Windows::Networking::Sockets;
using namespace winrt::Windows::Storage::Streams;

//const int VideoCameraStreamer::kImageWidth = 640;
//const wchar_t VideoCameraStreamer::kSensorName[3] = L"PV";
//const long long VideoCameraStreamer::kMinDelta = 2000000 ; // require 200 ms between frames; results in 5 fps


VideoCameraStreamer::VideoCameraStreamer(
    const SpatialCoordinateSystem& coordSystem,
    std::wstring portName)
{
    m_worldCoordSystem = coordSystem;
    m_portName = portName;

    StartServer();
    // m_streamingEnabled = true;
}

//IAsyncAction VideoCameraStreamer::StartServer()
//{
//    try
//    {
//        // The ConnectionReceived event is raised when connections are received.
//        m_streamSocketListener.ConnectionReceived({ this, &VideoCameraStreamer::OnConnectionReceived });
//
//        // Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use.
//        // Every protocol typically has a standard port number. For example, HTTP is typically 80, FTP is 20 and 21, etc.
//        // For this example, we'll choose an arbitrary port number.
//        co_await m_streamSocketListener.BindServiceNameAsync(m_portName);
//        //m_streamSocketListener.Control().KeepAlive(true);
//
//#if DBG_ENABLE_INFO_LOGGING       
//        wchar_t msgBuffer[200];
//        swprintf_s(msgBuffer, L"VideoCameraStreamer::StartServer: Server is listening at %ls \n",
//            m_portName.c_str());
//        OutputDebugStringW(msgBuffer);
//#endif
//    }
//    catch (winrt::hresult_error const& ex)
//    {
//#if DBG_ENABLE_ERROR_LOGGING
//        SocketErrorStatus webErrorStatus{ SocketError::GetStatus(ex.to_abi()) };
//        winrt::hstring message = webErrorStatus != SocketErrorStatus::Unknown ?
//            winrt::to_hstring((int32_t)webErrorStatus) : winrt::to_hstring(ex.to_abi());
//        OutputDebugStringW(L"VideoCameraStreamer::StartServer: Failed to open listener with ");
//        OutputDebugStringW(message.c_str());
//        OutputDebugStringW(L"\n");
//#endif
//    }
//}

IAsyncAction VideoCameraStreamer::StartServer()
{
    try
    {
        // The MessageReceived event is raised when a Message is received.
        m_serverDatagramSocket.MessageReceived({ this, &VideoCameraStreamer::ServerDatagramSocket_MessageReceived });

        // Start listening for incoming UDP connections on the specified port. You can specify any port that's not currently in use.
        co_await m_serverDatagramSocket.BindServiceNameAsync(m_portName);
#if DBG_ENABLE_INFO_LOGGING       
        wchar_t msgBuffer[200];
        swprintf_s(msgBuffer, L"VideoCameraStreamer::StartServer: Server is listening at %ls \n",
            m_portName.c_str());
        OutputDebugStringW(msgBuffer);
#endif
    }
    catch (winrt::hresult_error const& ex)
    {
#if DBG_ENABLE_ERROR_LOGGING
        SocketErrorStatus webErrorStatus{ SocketError::GetStatus(ex.to_abi()) };
        winrt::hstring message = webErrorStatus != SocketErrorStatus::Unknown ?
            winrt::to_hstring((int32_t)webErrorStatus) : winrt::to_hstring(ex.to_abi());
        OutputDebugStringW(L"VideoCameraStreamer::StartServer: Failed to open listener with ");
        OutputDebugStringW(message.c_str());
        OutputDebugStringW(L"\n");
#endif
    }
}

//void VideoCameraStreamer::OnConnectionReceived(
//    StreamSocketListener /* sender */,
//    StreamSocketListenerConnectionReceivedEventArgs args)
//{
//    try
//    {
//        m_streamSocket = args.Socket();
//        m_writer = DataWriter(args.Socket().OutputStream());
//        m_writer.UnicodeEncoding(UnicodeEncoding::Utf8);
//        m_writer.ByteOrder(ByteOrder::LittleEndian);
//
//        m_writeInProgress = false;
//        isConnected = true;
//#if DBG_ENABLE_INFO_LOGGING
//        OutputDebugStringW(L"VideoCameraStreamer::OnConnectionReceived: Received connection! \n");
//#endif
//    }
//    catch (winrt::hresult_error const& ex)
//    {
//#if DBG_ENABLE_ERROR_LOGGING
//        SocketErrorStatus webErrorStatus{ SocketError::GetStatus(ex.to_abi()) };
//        winrt::hstring message = webErrorStatus != SocketErrorStatus::Unknown ?
//            winrt::to_hstring((int32_t)webErrorStatus) : winrt::to_hstring(ex.to_abi());
//        OutputDebugStringW(L"VideoCameraStreamer::StartServer: Failed to establish connection with ");
//        OutputDebugStringW(message.c_str());
//        OutputDebugStringW(L"\n");
//#endif
//    }
//}

void VideoCameraStreamer::ServerDatagramSocket_MessageReceived(
    winrt::Windows::Networking::Sockets::DatagramSocket sender,
    winrt::Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs args)
{
    try {
        IBuffer buffer = args.GetDataReader().ReadBuffer(args.GetDataReader().UnconsumedBufferLength());
        std::string message{ reinterpret_cast<const char*>(buffer.data()), buffer.Length() };

#if DBG_ENABLE_INFO_LOGGING
        wchar_t msgBuffer[200];
        swprintf_s(msgBuffer, L"VideoCameraStreamer::ServerDatagramSocket_MessageReceived: Reveive text: %ls \n", message);
        OutputDebugStringW(msgBuffer);
#endif

        // send it back for test
        m_serverDatagramSocket.ConnectAsync(args.RemoteAddress(), args.RemotePort());
        m_writer = DataWriter{ m_serverDatagramSocket.OutputStream() };
        m_writer.UnicodeEncoding(UnicodeEncoding::Utf8);
        m_writer.ByteOrder(ByteOrder::LittleEndian);
        m_writer.WriteString(winrt::to_hstring(message));
        m_writer.StoreAsync();

        m_writeInProgress = false;
        isConnected = true;
#if DBG_ENABLE_INFO_LOGGING
        OutputDebugStringW(L"VideoCameraStreamer::ServerDatagramSocket_MessageReceived: Send OK! \n");
#endif
    }
    catch (winrt::hresult_error const& ex)
    {
#if DBG_ENABLE_ERROR_LOGGING
        SocketErrorStatus webErrorStatus{ SocketError::GetStatus(ex.to_abi()) };
        winrt::hstring message = webErrorStatus != SocketErrorStatus::Unknown ?
            winrt::to_hstring((int32_t)webErrorStatus) : winrt::to_hstring(ex.to_abi());
        OutputDebugStringW(L"VideoCameraStreamer::StartServer: Failed to establish connection with ");
        OutputDebugStringW(message.c_str());
        OutputDebugStringW(L"\n");
#endif
    }
}

// send a frame
void VideoCameraStreamer::Send(
    MediaFrameReference pFrame,
    long long pTimestamp)
{
#if DBG_ENABLE_VERBOSE_LOGGING
    OutputDebugStringW(L"VideoCameraStreamer::SendFrame: Received frame for sending!\n");
#endif
    if (!m_streamSocket || !m_writer)
    {
#if DBG_ENABLE_VERBOSE_LOGGING
        OutputDebugStringW(
            L"VideoCameraStreamer::SendFrame: No connection.\n");
#endif
        return;
    }


    // grab the frame info
    float fx = pFrame.VideoMediaFrame().CameraIntrinsics().FocalLength().x;
    float fy = pFrame.VideoMediaFrame().CameraIntrinsics().FocalLength().y;

    winrt::Windows::Foundation::Numerics::float4x4 PVtoWorldtransform;
    auto PVtoWorld =
        pFrame.CoordinateSystem().TryGetTransformTo(m_worldCoordSystem);
    if (PVtoWorld)
    {
        PVtoWorldtransform = PVtoWorld.Value();
    }
    else
    {
#if DBG_ENABLE_VERBOSE_LOGGING
        OutputDebugStringW(L"Streamer::SendFrame: Could not locate frame.\n");
#endif
        return;
    }

    // grab the frame data
    SoftwareBitmap softwareBitmap = SoftwareBitmap::Convert(
        pFrame.VideoMediaFrame().SoftwareBitmap(), BitmapPixelFormat::Bgra8);

    int imageWidth = softwareBitmap.PixelWidth();
    int imageHeight = softwareBitmap.PixelHeight();

    int pixelStride = 4;
    int scaleFactor = 1;

    int rowStride = imageWidth * pixelStride;

    // Get bitmap buffer object of the frame
    BitmapBuffer bitmapBuffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode::Read);

    // Get raw pointer to the buffer object
    uint32_t pixelBufferDataLength = 0;
    uint8_t* pixelBufferData;

    auto spMemoryBufferByteAccess{ bitmapBuffer.CreateReference()
        .as<::Windows::Foundation::IMemoryBufferByteAccess>() };

    try
    {
        spMemoryBufferByteAccess->
            GetBuffer(&pixelBufferData, &pixelBufferDataLength);
    }
    catch (winrt::hresult_error const& ex)
    {
#if DBG_ENABLE_ERROR_LOGGING
        winrt::hresult hr = ex.code(); // HRESULT_FROM_WIN32
        winrt::hstring message = ex.message();
        OutputDebugStringW(L"VideoCameraStreamer::SendFrame: Failed to get buffer with ");
        OutputDebugStringW(message.c_str());
        OutputDebugStringW(L"\n");
#endif
    }

    std::vector<uint8_t> imageBufferAsVector;
    for (int row = 0; row < imageHeight; row += scaleFactor)
    {
        for (int col = 0; col < rowStride; col += scaleFactor * pixelStride)
        {
            for (int j = 0; j < pixelStride - 1; j++)
            {
                imageBufferAsVector.emplace_back(
                    pixelBufferData[row * rowStride + col + j]);
            }
        }
    }

    if (m_writeInProgress)
    {
#if DBG_ENABLE_VERBOSE_LOGGING
        OutputDebugStringW(
            L"VideoCameraStreamer::SendFrame: Write in progress.\n");
#endif
        return;
    }
    m_writeInProgress = true;
    try
    {
        // Write header
        m_writer.WriteUInt64(pTimestamp);
        m_writer.WriteInt32(imageWidth);
        m_writer.WriteInt32(imageHeight);
        m_writer.WriteInt32(pixelStride - 1);
        m_writer.WriteInt32(imageWidth * (pixelStride - 1)); // adapted row stride
        m_writer.WriteSingle(fx);
        m_writer.WriteSingle(fy);

        WriteMatrix4x4(PVtoWorldtransform);

        m_writer.WriteBytes(imageBufferAsVector);
        m_writer.StoreAsync();
    }
    catch (winrt::hresult_error const& ex)
    {
        SocketErrorStatus webErrorStatus{ SocketError::GetStatus(ex.to_abi()) };
        if (webErrorStatus == SocketErrorStatus::ConnectionResetByPeer)
        {
            // the client disconnected!
            m_writer == nullptr;
            m_streamSocket == nullptr;
            m_serverDatagramSocket == nullptr;
            m_writeInProgress = false;
        }
#if DBG_ENABLE_ERROR_LOGGING
        winrt::hstring message = ex.message();
        OutputDebugStringW(L"VideoCameraStreamer::SendFrame: Sending failed with ");
        OutputDebugStringW(message.c_str());
        OutputDebugStringW(L"\n");
#endif // DBG_ENABLE_ERROR_LOGGING
    }

    m_writeInProgress = false;

#if DBG_ENABLE_VERBOSE_LOGGING
    OutputDebugStringW(
        L"VideoCameraStreamer::SendFrame: Frame sent!\n");
#endif

}

void VideoCameraStreamer::WriteMatrix4x4(
    _In_ winrt::Windows::Foundation::Numerics::float4x4 matrix)
{
    m_writer.WriteSingle(matrix.m11);
    m_writer.WriteSingle(matrix.m12);
    m_writer.WriteSingle(matrix.m13);
    m_writer.WriteSingle(matrix.m14);

    m_writer.WriteSingle(matrix.m21);
    m_writer.WriteSingle(matrix.m22);
    m_writer.WriteSingle(matrix.m23);
    m_writer.WriteSingle(matrix.m24);

    m_writer.WriteSingle(matrix.m31);
    m_writer.WriteSingle(matrix.m32);
    m_writer.WriteSingle(matrix.m33);
    m_writer.WriteSingle(matrix.m34);

    m_writer.WriteSingle(matrix.m41);
    m_writer.WriteSingle(matrix.m42);
    m_writer.WriteSingle(matrix.m43);
    m_writer.WriteSingle(matrix.m44);
}

sinkers-lan avatar May 16 '23 13:05 sinkers-lan