참고하여 수정함.
속도는 빨라짐. 깜빡임 발생.. 이미지를 계속해서 뿌리는 것이니까, 동영상으로 변경해야 함.
RGB 데이터를 요청함.
- snippet.cpp
//RGB나 YUV의 경우 헤더가 없음 char* pVideoBuffer = (char *)pData; BITMAPINFOHEADER bmih; bmih.biSize = sizeof(BITMAPINFOHEADER); bmih.biWidth = nWidth; bmih.biHeight = nHeight; bmih.biPlanes = 1; bmih.biBitCount = 24; bmih.biCompression = BI_RGB; bmih.biSizeImage = 0; bmih.biXPelsPerMeter = 10; bmih.biYPelsPerMeter = 10; bmih.biClrUsed = 0; bmih.biClrImportant = 0; BITMAPINFO dbmi; ZeroMemory(&dbmi, sizeof(dbmi)); dbmi.bmiHeader = bmih; dbmi.bmiColors->rgbBlue = 0; dbmi.bmiColors->rgbGreen = 0; dbmi.bmiColors->rgbRed = 0; dbmi.bmiColors->rgbReserved = 0; HDC hdc = ::GetDC(NULL); HBITMAP hbmp = CreateDIBitmap(hdc, &bmih, CBM_INIT, pVideoBuffer, &dbmi, DIB_RGB_COLORS); CWnd* pWnd = AfxGetApp()->GetMainWnd(); HWND hWnd = pWnd->GetSafeHwnd(); CStatic* m_staticPic2 = (CStatic*)pWnd->GetDlgItem(IDC_STATIC_PIC2); m_staticPic2->SetBitmap(hbmp); ::ReleaseDC(NULL, hdc); DeleteObject(hbmp);
해결방법::
AfxGetMainWnd() 대신 AfxGetApp()→GetMainWnd() 라고 쓰면된다. 참고
느리지만 나온다.
- snippet.cpp
CImage img; img.Create(nWidth, nHeight, 24); int nPixel = 0; for (int row = 0; row < nHeight; row++) { for (int col = 0; col < nWidth; col++) { BYTE r = pVideoBuffer[nPixel++]; BYTE g = pVideoBuffer[nPixel++]; BYTE b = pVideoBuffer[nPixel++]; img.SetPixel(col, row, RGB(r, g, b)); } } CBitmap* pBitmap = CBitmap::FromHandle(img); CWnd* pWnd = AfxGetApp()->GetMainWnd(); HWND hWnd = pWnd->GetSafeHwnd(); CStatic* m_staticPic2 = (CStatic*)pWnd->GetDlgItem(IDC_STATIC_PIC2); m_staticPic2->SetBitmap((HBITMAP)pBitmap->GetSafeHandle());
저장하는 코드로, 들어오는 포맷을 확인함.
- snippet.cpp
FILE *fp; static int nNum = 0; char szFilename[1024]; sprintf(szFilename, "C:\\9.test\\img\\head%d.jpg", nNum); fp = fopen(szFilename, "wb"); fwrite(pData, nDataSize, 1, fp); fclose(fp); sprintf(szFilename, "C:\\9.test\\img\\body%d.jpg", nNum); fp = fopen(szFilename, "wb"); fwrite(pVideoBuffer, nDataSize - videoHeaderSize, 1, fp); fclose(fp); nNum++;
요청 형식에 따라 들어오는 포맷이 달라짐.
- snippet.cpp
EXTERN_C INTEROPLIB_API bool W4NVMS_StartLiveVideo(int nDeviceID, int nStreamDataType)
스트림 타입 | 값 | 설명 |
— | — | — |
Decompressed | - 1 | 압축을 풀었을 때 나오는 Color Format(RGB24 or YUYV422)형태로 그대로 리턴 |
RGB24 | 0 | 24 Bit RGB Format |
YUV422 | 1 | YUYV422 Format |
JPEG | 2 | JPEG Format |
H264 | 3 | H264 Format |
MPEG4 | 4 | MPEG4 Format |
ARGB | 5 | ARGB Format |
Custom | 32 | 사용자 정의 |
RAW | 64 | 카메라로부터 받은 Encoding 데이터 원본 |
MetaData | 128 | 메타 데이터 |
int max 값은 : 2147483647
1280 * 1024 = 1310720
Sundance.Interop.AirLiveTestDlg.cpp(315) : atlTraceGeneral - ROW:308 예외 발생: 'System.AccessViolationException'(Sundance.Interop.AirLiveTest.exe)
지역정보
- snippet.cpp
//videoStream에서 헤더 뒤에 영상 데이터가 있음 char *pVideoBuffer = (char *)(pData + videoHeaderSize);
pVideoBuffer에서 사이즈 만큼의 정보를 가져와야 한다. 사이즈는 nWidth * nHeight.
포인터에서 정보를 얻어, 화면에 이미지를 출력하는 창을 만들어야 한다.
- snippet.cpp
int size = nWidth * nHeight * nStreamDataType; unsigned char* pImgData = new unsigned char[size]; memcpy(pImgData, pVideoBuffer, size);
테스트코드를 작성하였으나, pdb 파일이 없다 하며, 에러 발산.
기본화면
Connect 버튼을 눌러서, 서버에 접속한다.
DeviceId을 44로 수정한 후에 StartVideo 버튼을 눌러서, 영상 정보를 받는다.
- snippet.cpp
void CALLBACK StreamDataCallBack(int nDeviceID, int nWidth, int nHeight, int nStreamDataType, LPBYTE pData, int nDataSize, wchar_t* strTime, LPVOID pUserParam) { int videoHeaderSize = sizeof(W4NVMS_StructRawVideoHeader); W4NVMS_StructRawVideoHeader* videoHeader = (W4NVMS_StructRawVideoHeader *)pData; //videoStream에서 헤더 뒤에 영상 데이터가 있음 char *pVideoBuffer = (char *)(pData + videoHeaderSize); }
관련 문서
Plugin Backlinks: 아무 것도 없습니다.