| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- /* UDPSocketCapture.cpp/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */
- /* This copyright was auto-generated on Sat Mar 5 01:05:53 UTC 2022 */
- #include "UDPSocketCapture.h"
- #include "HTTPRequest.h"
- #include "GoProStreamDemo.h"
- #ifndef snprintf
- #define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)
- #endif
- #define READ_BUFFER_SIZE 16384
- extern "C"
- {
- #include "demuxing_decoding.h"
- }
- #include "BufferNegotiator.h"
- UDPSocketCapture::UDPSocketCapture()
- {
- }
- UDPSocketCapture::~UDPSocketCapture()
- {
- Stop();
- }
- LONG GetStringRegKey(HKEY hKey, const std::string& strValueName, std::string& strValue)
- {
- CHAR szBuffer[512] = { 0 };
- DWORD dwBufferSize = sizeof(szBuffer);
- ULONG nError;
- nError = RegQueryValueExA(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
- if (ERROR_SUCCESS == nError)
- {
- strValue = szBuffer;
- }
- return nError;
- }
- int UDPSocketCapture::FindCamera(std::string& address)
- {
- int ret = -1;
- address = "";
- WSAData wsaData;
- if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
- {
- return 255;
- }
- std::string myaddr = "";
- address = "";
- char logbuf[100] = { 0 };
- char ac[80];
- if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR)
- {
-
- snprintf(logbuf, 100, "Error %d when getting local host name.\n", WSAGetLastError());
- OutputDebugStringA(logbuf);
- WSACleanup();
- return -1;
- }
- snprintf(logbuf, 100, "Host name is %s\n", ac);
- OutputDebugStringA(logbuf);
- struct hostent* phe = gethostbyname(ac);
- struct addrinfo* result = NULL;
- struct addrinfo* res = NULL;
- getaddrinfo(ac, NULL, NULL, &result);
- if (phe == 0)
- {
- OutputDebugStringA("Bad host lookup.\n");
- WSACleanup();
- return -1;
- }
- for (int i = 0; phe->h_addr_list[i] != 0; ++i)
- {
- struct in_addr addr;
- memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));
- snprintf(logbuf, 100, "Address %d: %s\n ", i , inet_ntoa(addr));
- OutputDebugStringA(logbuf);
- if ((int)addr.S_un.S_un_b.s_b1 == 172 && ((int)addr.S_un.S_un_b.s_b2 >= 20 && (int)addr.S_un.S_un_b.s_b2 <= 29) &&
- ((int)addr.S_un.S_un_b.s_b4 >= 50 && (int)addr.S_un.S_un_b.s_b4 <= 70))
- {
- address = inet_ntoa(addr);
- address.replace(address.length() - 1, 1, "1");
- ret = 0;
- }
- }
- WSACleanup();
- return ret;
- }
- void UDPSocketCapture::Start(int height)
- {
- if (!mStarted)
- {
- mHeight = height;
- this->mCaptureThread = std::thread(CaptureThread, this);
- this->mOutputThread = std::thread(OutputThread, this);
- mStarted = true;
- }
- }
- void UDPSocketCapture::Stop()
- {
- if (mStarted)
- {
- StopDecoding();
- StopCapture();
- mQuitNow = true;
- if (mCaptureThread.joinable())
- mCaptureThread.join();
- if(mOutputThread.joinable())
- mOutputThread.join();
- mStarted = false;
- }
- }
- void UDPSocketCapture::GetBuffer(uint8_t* buf, long bufsize, long& bytesReturned)
- {
- mBufMutex.lock();
- static size_t actualbytes = 0;
- if (buf == NULL || bufsize == 0)
- {
- mBufMutex.unlock();
- return;
- }
- bytesReturned = ::GetBuffer(buf, bufsize);
- if (bytesReturned == 0)
- {
- if (mBigBuf == NULL)
- {
- char path[MAX_PATH];
- std::string spath = "";
- HMODULE hm = NULL;
- if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- (LPCSTR)&GetStringRegKey, &hm) == 0)
- {
- int err = GetLastError();
- fprintf(stderr, "GetModuleHandle failed, error = %d\n", err);
- }
- if (GetModuleFileNameA(hm, path, sizeof(path)) == 0)
- {
- int err = GetLastError();
- fprintf(stderr, "GetModuleFileName failed, error = %d\n", err);
- }
- spath = path;
- size_t slashpos = spath.find_last_of("\\", spath.length()) + 1;
- #ifdef USE_PREVIEW_STREAM
- spath.replace(slashpos, spath.length() - slashpos, "raw720.img");
- #else
- spath.replace(slashpos, spath.length() - slashpos, "raw.img");
- #endif
- mBigBuf = (uint8_t*)malloc(BIG_BUF_SIZE);
- if (mBigBuf != NULL)
- {
- FILE* ou = fopen(spath.c_str(), "rb");
- if (ou)
- {
- actualbytes = fread(mBigBuf, 1, BIG_BUF_SIZE, ou);
- fclose(ou);
- bytesReturned = actualbytes;
- }
- else
- {
- free(mBigBuf);
- mBigBuf = NULL;
- }
- }
- }
- if (mBigBuf != NULL)
- {
- if (bufsize!=0 && bufsize >= actualbytes)
- {
- memcpy(buf, mBigBuf, actualbytes);
- bytesReturned = actualbytes;
- }
- }
-
- }
- mBufMutex.unlock();
- }
- void UDPSocketCapture::WriteBuffer(uint8_t* buf, int bufsize)
- {
- mBufMutex.lock();
- mBufMutex.unlock();
- }
- /*
- This function is responsible for calling decode on the captured buffer
- */
- void UDPSocketCapture::OutputThread(UDPSocketCapture* me)
- {
- std::string addr = "";
-
- while (FindCamera(addr) != 0 && !me->mQuitNow)
- {
- Sleep(500);
- }
- if (!me->mQuitNow)
- {
- bool alreadyStarted = false;
- {
- HTTPRequest req(addr, 8080);
- if (req.get_request("/gopro/webcam/status"))
- {
- std::string stat = req.get_response();
- std::string findme = "\"status\": 2";
- if (stat.find(findme, 0) != std::string::npos)
- alreadyStarted = true;
- }
- if (alreadyStarted)
- {
- HTTPRequest req(addr, 8080);
- if (req.get_request("/gopro/webcam/stop"))
- {
- std::string stat = req.get_response();
- }
- Sleep(200);
- }
- }
- {
- HTTPRequest req(addr, 8080);
- #ifdef USE_PREVIEW_STREAM
- std::string startaddr = "/gopro/camera/stream/start";
- #else
- std::string startaddr = "/gopro/webcam/start?res=%d&fov=0";
- #endif
-
- char bufff[256] = { 0 };
- int parm = 12;
- if(me->mHeight == 720)
- {
- parm = 7;
- }
- snprintf(bufff, 256, startaddr.c_str(), parm);
- std::string buf = bufff;
- if (req.get_request(buf))
- {
- std::string stat = req.get_response();
- }
- }
- const char* url = "udp://@0.0.0.0:8554";
- while (!me->mQuitNow)
- {
- try
- {
- DecodeStream();
- }
- catch (...)
- {
- OutputDebugStringA("Decode crashed, quitting everything\n");
- }
- }
- {
- HTTPRequest req(addr, 8080);
- #ifdef USE_PREVIEW_STREAM
- req.get_request("/gopro/camera/stream/stop");
- #else
- req.get_request("/gopro/webcam/stop");
- if (!req.TimedOut)
- {
- HTTPRequest req2(addr, 8080);
- req2.get_request("/gopro/webcam/exit");
- }
- #endif
- }
- }
-
- OutputDebugStringA("LEAVING THREAD\n");
- }
- /*
- This is the main function that captures TS data from the camera and saves it to a buffer
- */
- void UDPSocketCapture::CaptureThread(UDPSocketCapture* me)
- {
- WSASession session;
- char buf[READ_BUFFER_SIZE] = { 0 };
- OutputDebugStringA("Starting receive thread\n");
- UDPSocket* mysock = new UDPSocket();
- mysock->Bind(8554);
- while (true)
- {
- if (mysock == NULL)
- {
- mysock = new UDPSocket();
- mysock->Bind(8554);
- }
- int received = 0;
- sockaddr_in blop = mysock->RecvFrom(buf, READ_BUFFER_SIZE, received);
- //LOGF::Instance()->LOG("Received %d bytes\n", received);
- if (received == READ_BUFFER_SIZE)
- OutputDebugStringA("Maxed out the buffer\n");
- if (received == 1 || me->mQuitNow)
- {
- //fclose(myfile);
- break;
- }
- WriteInputBuffer((uint8_t*)buf, received);
-
- memset(buf, 0, READ_BUFFER_SIZE);
- }
- }
- void UDPSocketCapture::StopCapture()
- {
- UDPSocket soc;
- char buf = 'q';
- soc.SendTo("127.0.0.1", 8554, &buf, 1);
- StopInput();
- }
|