123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- void HaiKangHelper::yv12toYuv(const quint8 *yuv420, quint8 *y, quint8 *u, quint8 *v, int width, int height)
- {
- //Y分量的长度
- int yLen = width * height;
- //U和V分量的长度
- int uvLen = width / 2 * height / 2;
- //海康的uv是反的需要反过来否则颜色发蓝
- memcpy((quint8 *)y, yuv420, yLen);
- memcpy((quint8 *)v, yuv420 + yLen, uvLen);
- memcpy((quint8 *)u, yuv420 + yLen + uvLen, uvLen);
- }
- void HaiKangHelper::yv12toYuv(const quint8 *yv12, quint8 *yuv, int width, int height, int widthStep)
- {
- int col, row;
- int tmp, idx;
- uint y, u, v;
- for (row = 0; row < height; row++) {
- idx = row * widthStep;
- for (col = 0; col < width; col++) {
- tmp = (row / 2) * (width / 2) + (col / 2);
- y = (uint)yv12[row * width + col];
- u = (uint)yv12[width * height + width * height / 4 + tmp];
- v = (uint)yv12[width * height + tmp];
- yuv[idx + col * 3] = y;
- yuv[idx + col * 3 + 1] = u;
- yuv[idx + col * 3 + 2] = v;
- }
- }
- }
- void HaiKangHelper::ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
- {
- //具体类型含义看头文件或者手册即可
- HaiKangThread *thread = (HaiKangThread *)pUser;
- thread->debug("异常回调", "");
- switch (dwType) {
- case EXCEPTION_RECONNECT:
- thread->debug("超时重连", "");
- break;
- default:
- break;
- }
- }
- void HaiKangHelper::RealDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void *pUser)
- {
- //每个类都对应自己的port
- HaiKangCallbackData *callbackData = (HaiKangCallbackData *)pUser;
- HaiKangThread *thread = callbackData->thread;
- LONG nPort = thread->port;
- DWORD dRet;
- switch (dwDataType) {
- case NET_DVR_SYSHEAD:
- //获取播放库未使用的通道号
- if (!PlayM4_GetPort(&nPort)) {
- break;
- }
- if (dwBufSize > 0) {
- thread->port = nPort;
- if (!PlayM4_OpenStream(nPort, pBuffer, dwBufSize, 1024 * 1024)) {
- dRet = PlayM4_GetLastError(nPort);
- break;
- }
- //设置解码回调函数,只解码不显示
- bool result = PlayM4_SetDecCallBackMend(nPort, DecCallBack, pUser);
- if (!result) {
- dRet = PlayM4_GetLastError(nPort);
- break;
- }
- //打开视频解码
- if (!PlayM4_Play(nPort, NULL)) {
- dRet = PlayM4_GetLastError(nPort);
- break;
- }
- //打开音频解码,需要码流是复合流
- if (!PlayM4_PlaySound(nPort)) {
- dRet = PlayM4_GetLastError(nPort);
- break;
- }
- }
- break;
- case NET_DVR_STREAMDATA:
- //解码数据
- if (dwBufSize > 0 && nPort != -1) {
- BOOL inData = PlayM4_InputData(nPort, pBuffer, dwBufSize);
- while (!inData) {
- //sleep(10);
- qApp->processEvents();
- inData = PlayM4_InputData(nPort, pBuffer, dwBufSize);
- }
- }
- break;
- }
- }
- void HaiKangHelper::FileEndCallback(LONG nPort, void *pUser)
- {
- HaiKangThread *thread = (HaiKangThread *)pUser;
- thread->stop2();
- }
- //void HaiKangHelper::DecCallBack(LONG nPort, char *pBuf, LONG nSize, FRAME_INFO *pFrameInfo, LONG pUser, LONG nReserved2)
- #ifdef Q_OS_WIN
- void HaiKangHelper::DecCallBack(LONG nPort, char *pBuf, LONG nSize, FRAME_INFO *pFrameInfo, void *pUser, void *nReserved2)
- #else
- void HaiKangHelper::DecCallBack(LONG nPort, char *pBuf, LONG nSize, FRAME_INFO *pFrameInfo, void *pUser, LONG nReserved2)
- #endif
- {
- HaiKangCallbackData *callbackData = (HaiKangCallbackData *)pUser;
- HaiKangThread *thread = callbackData->thread;
- if (thread->getIsPause()) {
- return;
- }
- quint8 *data = (quint8 *)pBuf;
- long frameType = pFrameInfo->nType;
- //编码时产生的图像帧率(如果是音频数据则为采样率)
- long frameRate = pFrameInfo->nFrameRate;
- //视频数据是 T_YV12 音频数据是 T_AUDIO16
- if (frameType == T_YV12) {
- long width = pFrameInfo->nWidth;
- long height = pFrameInfo->nHeight;
- //识别尺寸发生变化
- thread->checkVideoSize(width, height);
- //thread->debug("回调视频", QString("宽高: %1x%2").arg(width).arg(height));
- //如果处于截图标志位则立即将图片保存
- if (thread->getIsSnap()) {
- QImage image(width, height, QImage::Format_RGB888);
- yv12ToRgb888(data, image.bits(), width, height);
- image.save(thread->getSnapName(), "jpg");
- QMetaObject::invokeMethod(thread, "snapFinsh");
- }
- //如果是绘制则转成图片否则转成yuv用opengl绘制
- if (thread->getVideoMode() == VideoMode_Opengl) {
- yv12toYuv(data, callbackData->dataY, callbackData->dataU, callbackData->dataV, width, height);
- thread->setYuv(width, height, callbackData->dataY, callbackData->dataU, callbackData->dataV);
- } else {
- QImage image(width, height, QImage::Format_RGB888);
- yv12ToRgb888(data, image.bits(), width, height);
- thread->setImage(image);
- }
- } else if (frameType == T_AUDIO16) {
- //thread->debug("回调音频", QString("采样: %1").arg(frameRate));
- }
- }
|