참고하여 수정함.
속도는 빨라짐. 깜빡임 발생.. 이미지를 계속해서 뿌리는 것이니까, 동영상으로 변경해야 함.
RGB 데이터를 요청함.
//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() 라고 쓰면된다. 참고
느리지만 나온다.
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());
저장하는 코드로, 들어오는 포맷을 확인함.
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++;
요청 형식에 따라 들어오는 포맷이 달라짐.
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)
지역정보
//videoStream에서 헤더 뒤에 영상 데이터가 있음 char *pVideoBuffer = (char *)(pData + videoHeaderSize);
pVideoBuffer에서 사이즈 만큼의 정보를 가져와야 한다. 사이즈는 nWidth * nHeight.
포인터에서 정보를 얻어, 화면에 이미지를 출력하는 창을 만들어야 한다.
int size = nWidth * nHeight * nStreamDataType; unsigned char* pImgData = new unsigned char[size]; memcpy(pImgData, pVideoBuffer, size);
테스트코드를 작성하였으나, pdb 파일이 없다 하며, 에러 발산.
기본화면
Connect 버튼을 눌러서, 서버에 접속한다.
DeviceId을 44로 수정한 후에 StartVideo 버튼을 눌러서, 영상 정보를 받는다.
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); }