int capture_devCbOnFrame(void *pArg, const unsigned char *pData, unsigned int len) { int rc = 0; COLLECT_STREAM_PKTDATA_T pktdata; CAP_DEV_CFG_T *pCapDevCfg = (CAP_DEV_CFG_T *) pArg; if(!pCapDevCfg || !pCapDevCfg->pmtx) { return -1; } VSX_DEBUGLOG("capture_devCbOnFrame len:%d %s\n", len, codecType_getCodecDescrStr(pCapDevCfg->pStream->pFilter->mediaType)); timer_getPreciseTime(&pktdata.tv); PKTLEN32(pktdata.payload) = len; pktdata.payload.pData = (unsigned char *) pData; //fprintf(stderr, "capture_devCbOnFrame len:%d 0x%x '%s' %u:%u\n",len, pCapDevCfg->pStream->pCbUserData, pCapDevCfg->pCapCfg->pcommon->localAddrs[pCapDevCfg->idxFilter], pktdata.tv.tv_sec, pktdata.tv.tv_usec); //__android_log_print(ANDROID_LOG_INFO, "vsx", "capture_devCbOnFrame len:%d 0x%x '%s'\n",len, pCapDevCfg->pStream->pCbUserData, pCapDevCfg->pCapCfg->pcommon->localAddrs[pCapDevCfg->idxFilter]); pthread_mutex_lock(pCapDevCfg->pmtx); rc = pCapDevCfg->pStream->cbOnPkt(pCapDevCfg->pStream->pCbUserData, (const COLLECT_STREAM_PKTDATA_T *) &pktdata); pthread_mutex_unlock(pCapDevCfg->pmtx); return rc; }
int cbOnPkt_rawdev(void *pUserData, const COLLECT_STREAM_PKTDATA_T *pPktData) { int rc = 0; CAP_QUEUERAW_FRAME_DATA_T cbQueueFr; CAPTURE_CBDATA_SP_T *pSp = (CAPTURE_CBDATA_SP_T *) pUserData; CAPTURE_STORE_CBDATA_T cbData; int queueFr = 0; if(pSp == NULL) { return -1; } else if(!pPktData || !pPktData->payload.pData) { // Frame is missing or lost LOG(X_WARNING("Missing rawdev frame")); return 0; } //fprintf(stderr, "cbOnPkt_rawdev %u:%u len:%d\n", pPktData->tv.tv_sec, pPktData->tv.tv_usec, PKTLEN32(pPktData->payload)); memset(&cbData, 0, sizeof(cbData)); if(pSp->pCapAction && (pSp->pCapAction->cmd & CAPTURE_PKT_ACTION_QUEUEFRAME)) { queueFr = 1; } if(queueFr) { cbQueueFr.pSp = pSp; cbQueueFr.pPktData = pPktData; cbData.pCbDataArg = (void *) &cbQueueFr; cbData.cbStoreData = capture_cbQueueRawDevFrame; } else if(pSp->stream1.fp != FILEOPS_INVALID_FP) { cbData.pCbDataArg = &pSp->stream1; cbData.cbStoreData = capture_cbWriteFile; } else { // Nothing to be done return 0; } rc = cbData.cbStoreData(cbData.pCbDataArg, pPktData->payload.pData, PKTLEN32(pPktData->payload)); return rc; }
static int capture_cbQueueRawDevFrame(void *pArg, const void *pData, uint32_t szData) { int rc = 0; CAP_QUEUERAW_FRAME_DATA_T *pFrameData = (CAP_QUEUERAW_FRAME_DATA_T *) pArg; PKTQ_EXTRADATA_T xtra; xtra.tm.pts = ((uint64_t)pFrameData->pPktData->tv.tv_sec * 90000) + ((double)pFrameData->pPktData->tv.tv_usec / TIME_VAL_US * 90000); xtra.tm.dts = 0; //xtra.flags = CAPTURE_SP_FLAG_KEYFRAME; xtra.pQUserData = NULL; //fprintf(stderr, "capture_cbWriteRawDevFrame len:%d %.3f(%llu) tv:%u:%u \n", szData, PTSF(xtra.tm.pts), xtra.tm.pts, pFrameData->pPktData->tv.tv_sec, pFrameData->pPktData->tv.tv_usec); rc = pktqueue_addpkt(pFrameData->pSp->pCapAction->pQueue, pFrameData->pPktData->payload.pData, PKTLEN32(pFrameData->pPktData->payload), &xtra, 1); return rc; }
static int readFramesFromDev(CAP_DEV_CFG_T *pCapDevCfg) { int rc = 0; TIME_VAL tv0, tv, tvSleep, tvStart; TIME_VAL tvElapsed = 0; TIME_VAL tvMark = 0; unsigned int frameIdx = 0; COLLECT_STREAM_PKTDATA_T pktdata; CAP_DEV_CTXT_T capDevCtxt; CAPTURE_FILTER_T *pFilter = &pCapDevCfg->pCapCfg->pcommon->filt.filters[pCapDevCfg->idxFilter]; //BMP_FILE_T bmp; //memset(&bmp, 0, sizeof(bmp)); memset(&capDevCtxt, 0, sizeof(capDevCtxt)); capDevCtxt.dev = pCapDevCfg->pCapCfg->pcommon->localAddrs[pCapDevCfg->idxFilter]; //capDevCtxt.dev = "./rawfmt.bmp"; if(readFramesSetup(pFilter, &capDevCtxt.frame) < 0) { return -1; } //TODO: seperate out and maintain better throttle mechanism tv0 = tvStart = timer_GetTime(); while(!g_proc_exit && pCapDevCfg->pCapCfg->running == 0) { // // Reading too slow, reset time reference // if(tvElapsed > tvMark + 300000) { LOG(X_WARNING("Resetting read time for %s after %llu ms > %llu ms (%.3ffps x %ufr)"), capDevCtxt.dev, tvElapsed / TIME_VAL_MS, (TIME_VAL)((1000.0f / pFilter->fps) * frameIdx), pFilter->fps, frameIdx); tv0 = timer_GetTime(); frameIdx = 0; } do { tv = timer_GetTime(); tvElapsed = (tv - tv0); tvMark = (frameIdx / pFilter->fps) * TIME_VAL_US; if(tvElapsed < tvMark) { if((tvSleep = (tvMark - tvElapsed)) < 1000) { tvSleep = 1; } //fprintf(stderr, "sleeping %lld ns\n", tvSleep); usleep(tvSleep); tv = timer_GetTime(); tvElapsed = (tv - tv0); } } while(tvElapsed < tvMark); //if(frameIdx > 50) usleep(50000); //fprintf(stderr, "reading frame %d supposed to be:%lld at:%lld\n", frameIdx, (TIME_VAL) (frameIdx*1000.0f/pFilter->fps),(timer_GetTime() - tv0)/ TIME_VAL_MS); if((rc = readFrameFromDev(&capDevCtxt)) < 0) { break; } /* if((rc = bmp_create(&bmp, pFilter->mediaType, pFilter->width, pFilter->height, capDevCtxt.frame.pData)) < 0) { LOG(X_ERROR("Failed to create bmp %d x %d for format %d"), pFilter->width, pFilter->height, pFilter->mediaType); break; } PKTLEN32(pktdata.payload) = BMP_GET_LEN(&bmp); pktdata.payload.pData = BMP_GET_DATA(&bmp); */ pktdata.tv.tv_sec = (tv - tvStart) / TIME_VAL_US; pktdata.tv.tv_usec = (tv - tvStart) % TIME_VAL_US; PKTLEN32(pktdata.payload) = capDevCtxt.frame.len; pktdata.payload.pData = capDevCtxt.frame.pData; //fprintf(stderr, "got %d bmp %d from %s %llu\n", capDevCtxt.frame.len, BMP_GET_LEN(&bmp), capDevCtxt.dev, tv - tvStart); pCapDevCfg->pStream->cbOnPkt(&pCapDevCfg->pStreamCbData->sp[0], (const COLLECT_STREAM_PKTDATA_T *) &pktdata); frameIdx++; } if(capDevCtxt.fd > 0) { close(capDevCtxt.fd); } free(capDevCtxt.frame.pBuf); //bmp_destroy(&bmp); return rc; }