?? parse_capture_cmdline.c
字號:
capture_opt->DigitalTimingSignal, capture_opt->UseVideoValid, capture_opt->bussize, capture_opt->over_pos_x, capture_opt->over_pos_y, capture_opt->over_width, capture_opt->over_height, capture_opt->DualEdge, capture_opt->DualEdgeWidth, capture_opt->DualEdgeInvert, capture_opt->InputColorFormat, capture_opt->InputColorSpace, capture_opt->InvertVSync, capture_opt->InvertHSync, inv_fid, use_gpio); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error setting graphic input: %s\n", RMstatusToString(err))); return err; } } else if (capture_opt->InputModuleID == DispVideoInput) { if (capture_opt->bussize > 16) { RMDBGLOG((ENABLE, "video input can't capture 24 or 32 bit video!\n")); return RM_ERROR; } err = DCCSetupVideoInput(dcc_info->pDCC, capture_opt->TVStandard, capture_opt->DigitalTimingSignal, capture_opt->UseVideoValid, capture_opt->bussize, capture_opt->over_pos_x, capture_opt->over_pos_y, capture_opt->over_width, capture_opt->over_height, capture_opt->InvertVSync, capture_opt->InvertHSync, inv_fid, use_gpio); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error setting video input: %s\n", RMstatusToString(err))); return err; } } while ((err = RUASetProperty(dcc_info->pRUA, capture_opt->InputModuleID, RMGenericPropertyID_PictureOverride, &(capture_opt->override), sizeof(capture_opt->override), 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set PictureOverride on input: %s\n", RMstatusToString(err))); } if (! capture_opt->disablescaler) { // set surface into scaler err = DCCSetSurfaceSource(dcc_info->pDCC, dcc_info->SurfaceID, *ppVideoSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set the surface source %d\n", err)); return err; } } // set up VBI capture old_vbi_size = capture_opt->vbi_size; capture_opt->vbi_size = 0; // determine vbi capture mode and depending window size if (capture_opt->vbianc_enable) { capture_opt->vbi_h = capture_opt->vbianc_h * 2; // assume interlaced - TODO look at input format capture_opt->vbi_w = capture_opt->vbianc_w / 2; } else if (capture_opt->vbiraw_topmask || capture_opt->vbiraw_botmask) { RMuint32 top_lines, bot_lines, mask, i; top_lines = 0; mask = capture_opt->vbiraw_topmask; for (i = 0; i < 24; i++) { if (mask & 1) top_lines++; mask >>= 1; } bot_lines = 0; mask = capture_opt->vbiraw_botmask; for (i = 0; i < 24; i++) { if (mask & 1) bot_lines++; mask >>= 1; } capture_opt->vbi_h = ((top_lines > bot_lines) ? top_lines : bot_lines) * 2; // assume interlaced - TODO capture_opt->vbi_w = 720; // assume PAL or NTSC - TODO } // allocate VBI buffer if (capture_opt->vbi_w && capture_opt->vbi_h) { capture_opt->vbi_size = capture_opt->vbi_w * capture_opt->vbi_h * 2; if (capture_opt->vbi_dma) { if (ppR && ppDmaReceive) { struct Receive_type Receive; Receive.pRUA = dcc_info->pRUA; Receive.targetModule = EMHWLIB_TARGET_MODULE( EMHWLIB_MODULE_CATEGORY(capture_opt->InputModuleID), EMHWLIB_MODULE_INDEX(capture_opt->InputModuleID), 1); Receive.buffer_count = 4; Receive.buffer_size_log2 = 15; // 32k per buffer -> 128k Receive.threshold_size = 1 << Receive.buffer_size_log2; /* every buffer we receive interrupt */ Receive.partial_read = FALSE; err = DCCOpenReceive(&Receive, ppR, ppDmaReceive); }// capture_opt->vbi_buf = 0; capture_opt->vbi_size += 12; // size of one VBI data block, including header// if (ppVBIData) *ppVBIData = NULL; } else { if (ppVBIData) { if (((old_vbi_size / 300 - 12) != capture_opt->vbi_size) && *ppVBIData) { RMFree(*ppVBIData); *ppVBIData = NULL; if (capture_opt->vbi_buf) { RUAFree(dcc_info->pRUA, capture_opt->vbi_buf); capture_opt->vbi_buf = 0; } } if (! *ppVBIData) *ppVBIData = (RMuint16 *)RMMalloc(capture_opt->vbi_size); } capture_opt->vbi_size = (capture_opt->vbi_size + 12) * 300; // number of VBI buffers if (! capture_opt->vbi_buf) { capture_opt->vbi_buf = DCCMalloc(dcc_info->pDCC, 0, RUA_DRAM_UNCACHED, capture_opt->vbi_size); } printf("Storing 0x%08lX bytes of VBI data from 0x%08lX to 0x%08lX\n", capture_opt->vbi_size, capture_opt->vbi_buf, capture_opt->vbi_buf + capture_opt->vbi_size);// if (ppDmaReceive) *ppDmaReceive = NULL;// if (ppR) *ppR = NULL; } } // enable/disable ANC type vbi capture err = DCCSetupVBICaptureANC(dcc_info->pDCC, capture_opt->InputModuleID, capture_opt->vbianc_enable, capture_opt->vbianc_w, capture_opt->vbianc_h, capture_opt->vbianc_ytop, capture_opt->vbianc_ybot, capture_opt->vbi_dma ? 0 : capture_opt->vbi_buf, capture_opt->vbi_dma ? 0 : capture_opt->vbi_size); if (RMFAILED(err)) return err; // enable/disable Raw type vbi capture err = DCCSetupVBICaptureRaw(dcc_info->pDCC, capture_opt->InputModuleID, capture_opt->vbiraw_topstart, capture_opt->vbiraw_topmask, capture_opt->vbiraw_botstart, capture_opt->vbiraw_botmask, capture_opt->vbi_dma ? 0 : capture_opt->vbi_buf, capture_opt->vbi_dma ? 0 : capture_opt->vbi_size); if (RMFAILED(err)) return err; // enable 601 type vbi capture if ( (! capture_opt->vbianc_enable) && // is not ANC, (! (capture_opt->vbiraw_topmask || capture_opt->vbiraw_botmask)) && // is not Raw, capture_opt->vbi_w && capture_opt->vbi_h // but window defined --> is 601 ) { err = DCCSetupVBICapture(dcc_info->pDCC, capture_opt->InputModuleID, capture_opt->vbi_x, capture_opt->vbi_y, capture_opt->vbi_w, capture_opt->vbi_h, capture_opt->vbi_dma ? 0 : capture_opt->vbi_buf, capture_opt->vbi_dma ? 0 : capture_opt->vbi_size); if (RMFAILED(err)) return err; } return RM_OK;}RMstatus apply_capture_options( struct dcc_context *dcc_info, struct DCCVideoSource **ppVideoSource, struct capture_cmdline *options, RMuint16 **ppVBIData, struct ReceiveObject_type **ppR, struct RUABufferPool **ppDmaReceive, RMuint32 TimerNumber, RMbool use_gpio, RMbool inv_fid){ RMstatus err; // set up the input err = setup_capture(dcc_info, ppVideoSource, options, ppVBIData, ppR, ppDmaReceive, TimerNumber, use_gpio, inv_fid); if (RMFAILED(err)) return err; return RM_OK;}RMstatus guess_capture_format( struct dcc_context *dcc_info, struct capture_cmdline *options){ RMstatus err; RMuint64 XtalPerField = 0, ClocksPerField = 0, LinesPerField = 0, ClocksPerLine = 0; RMuint32 i, samples = 0; RMuint32 VFreq; // sample sets of values for averaging for (i = 0; i < 50; i++) { // half second struct Input_Detect_type det; err = RUAGetProperty(dcc_info->pRUA, options->InputModuleID, RMGenericPropertyID_Detect, &det, sizeof(det)); if (RMFAILED(err)) printf("Error getting property Detect: %s\n", RMstatusToString(err)); if (i >= 3) { // skip first three measurements XtalPerField += det.XtalPerField; ClocksPerField += det.ClocksPerField; LinesPerField += det.LinesPerField; ClocksPerLine += det.ClocksPerLine; samples++; } usleep(10000); } // average sampled values VFreq = XtalPerField ? 2700000000U / (RMuint32)(XtalPerField / samples) : 0; ClocksPerField /= samples; LinesPerField /= samples; ClocksPerLine /= samples; //printf("Guessing captured video format\n Measured values are: %ld.%02ld Hz, %ld pix/field, %ld lines/field, %ld pix/line\n", // VFreq / 100, VFreq % 100, // (RMuint32)ClocksPerField, // (RMuint32)LinesPerField, // (RMuint32)ClocksPerLine); // maintain minimum thresholds: 10 Hz, 10000 cpf, 48 lpf, 128 cpl if ( (VFreq && (VFreq < 1000)) || (ClocksPerField && (ClocksPerField < 10000)) || (LinesPerField && (LinesPerField < 48)) || (ClocksPerLine && (ClocksPerLine < 128)) ) { printf("No Video!\n"); return RM_ERROR; } // match with closest TVStandard { enum EMhwlibTVStandard prevTVStandard = options->TVStandard; enum EMhwlibTVStandard best_match = EMhwlibTVStandard_Custom; RMuint32 curr_VFreq, curr_ClocksPerField, curr_HalfLinesPerField, curr_ClocksPerLine; RMint32 diff_VFreq, diff_ClocksPerField, diff_LinesPerField, diff_ClocksPerLine; RMuint64 err, min_err = 0xFFFFFFFFFFFFFFFFULL; RMascii *StandardName; options->TVStandard = 1; while (RMSUCCEEDED(GetTVStandardName(options->TVStandard, &StandardName))) { struct EMhwlibTVFormatDigital dig; RMuint32 dig_clk; err = RUAExchangeProperty(dcc_info->pRUA, DisplayBlock, RMDisplayBlockPropertyID_TVFormatDigital, &(options->TVStandard), sizeof(options->TVStandard), &dig, sizeof(dig)); if RMFAILED(err) { RMDBGLOG((ENABLE, "Could not get format for TV Standard %s!\n", StandardName)); return err; } err = RUAExchangeProperty(dcc_info->pRUA, DisplayBlock, RMDisplayBlockPropertyID_TVPixelClockDigital, &(options->TVStandard), sizeof(options->TVStandard), &dig_clk, sizeof(dig_clk)); if RMFAILED(err) { RMDBGLOG((ENABLE, "Could not get pixel clock for TV Standard %s!\n", StandardName)); return err; } curr_HalfLinesPerField = dig.VTotalSize; if (! dig.TopFieldHeight) curr_HalfLinesPerField *= 2; curr_ClocksPerLine = dig.HTotalSize; if (options->bussize == 8) curr_ClocksPerLine *= 2; curr_ClocksPerField = curr_HalfLinesPerField * curr_ClocksPerLine / 2; if (options->bussize == 8) dig_clk *= 2; curr_VFreq = (RMuint32)((RMuint64)dig_clk * 100L / curr_ClocksPerField); if (0) printf("Mode: %s - %ld Hz, %ld.%02ld Hz, %ld pix/field, %ld lines/field, %ld pix/line\n", StandardName, dig_clk, curr_VFreq / 100, curr_VFreq % 100, curr_ClocksPerField, curr_HalfLinesPerField / 2, curr_ClocksPerLine); diff_VFreq = (VFreq) ? VFreq - curr_VFreq : 0; diff_ClocksPerField = (ClocksPerField) ? ClocksPerField - curr_ClocksPerField : 0; diff_LinesPerField = (LinesPerField) ? LinesPerField - curr_HalfLinesPerField / 2 : 0; diff_ClocksPerLine = (ClocksPerLine) ? ClocksPerLine - curr_ClocksPerLine : 0; err = diff_VFreq * diff_VFreq + diff_ClocksPerField * diff_ClocksPerField + diff_LinesPerField * diff_LinesPerField + diff_ClocksPerLine * diff_ClocksPerLine; if (0) printf("deviation: dist^2: %llu (min = %llu) diff: %s%d.%02d Hz, %ld pix/field, %ld lines/field, %ld pix/line\n", err, min_err, (diff_VFreq < 0) ? "-" : "", abs(diff_VFreq) / 100, abs(diff_VFreq) % 100, diff_ClocksPerField, diff_LinesPerField / 2, diff_ClocksPerLine); if (err < min_err) { min_err = err; best_match = options->TVStandard; } options->TVStandard ++; } if (best_match != EMhwlibTVStandard_Custom) { options->TVStandard = best_match; } else { options->TVStandard = prevTVStandard; } } return RM_OK;}RMstatus close_capture( struct dcc_context *dcc_info, struct DCCVideoSource **ppVideoSource, struct capture_cmdline *capture_opt, RMuint16 **ppVBIData, struct ReceiveObject_type **ppR, struct RUABufferPool **ppDmaReceive){ RMstatus err; // disable ANC type vbi capture err = DCCSetupVBICaptureANC(dcc_info->pDCC, capture_opt->InputModuleID, FALSE, 0, 0, 0, 0, 0, 0); if (RMFAILED(err)) return err; // disable Raw type vbi capture err = DCCSetupVBICaptureRaw(dcc_info->pDCC, capture_opt->InputModuleID, 0, 0, 0, 0, 0, 0); if (RMFAILED(err)) return err; // disable 601 type vbi capture err = DCCSetupVBICapture(dcc_info->pDCC, capture_opt->InputModuleID, 0, 0, 0, 0, 0, 0); if (RMFAILED(err)) return err; // close input and remove old surface if (ppVideoSource && *ppVideoSource) { //fprintf(stderr, "Closing VideoSource\n"); err = DCCCloseVideoSource(*ppVideoSource); *ppVideoSource = NULL; if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Could not clean surface: %s\n", RMstatusToString(err))); } } // TODO closing DMA fails, needs to be fixed!!! // close old VBI capture, if any if (ppR && *ppR) {// RMuint32 n; fprintf(stderr, "Closing DMA VBI receiver\n");// n = 25;// do {// if (ppDmaReceive && *ppDmaReceive) {// RMuint8 *pBuf = NULL;// RMuint32 size = 0;// RMuint32 targetModule = EMHWLIB_TARGET_MODULE(// EMHWLIB_MODULE_CATEGORY(capture_opt->InputModuleID), // EMHWLIB_MODULE_INDEX(capture_opt->InputModuleID), // 1);// fprintf(stderr, "Receiving remaining DMA buffers\n");// do {// err = RUAReceiveData(dcc_info->pRUA, targetModule, *ppDmaReceive, &pBuf, &size, NULL, NULL);// fprintf(stderr, "RUAReceiveData(): %s, %p, %lu\n", RMstatusToString(err), pBuf, size);// if (RMSUCCEEDED(err) && pBuf && size) {// RUAReleaseBuffer(*ppDmaReceive, pBuf);// }// } while (RMSUCCEEDED(err) /*|| (err == RM_PENDING)*/);// }// if ((*ppR)->pDMA) err = RUAResetPool((*ppR)->pDMA);// else err = RM_OK;// } while (--n && RMFAILED(err)); //DCCResetReceive(*ppR);// DCCCloseReceive(*ppR); //*ppR = NULL; } if (ppVBIData && *ppVBIData) { fprintf(stderr, "Releasing VBIData buffer\n"); RMFree(*ppVBIData); *ppVBIData = NULL; } if (capture_opt->vbi_buf) { fprintf(stderr, "Releasing vbi_buf\n"); DCCFree(dcc_info->pDCC, capture_opt->vbi_buf); capture_opt->vbi_buf = 0; } return err;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -