// card number passed as void * (using cast) static void * sdi_monitor(void *arg) { long card = (long)arg; sv_handle *sv = a_sv[card]; sv_fifo *poutput; sv_info status_info; sv_storageinfo storage_info; printf("card = %ld\n", card); SV_CHECK( sv_status( sv, &status_info) ); SV_CHECK( sv_storage_status(sv, 0, NULL, &storage_info, sizeof(storage_info), 0) ); SV_CHECK( sv_fifo_init( sv, &poutput, // FIFO handle FALSE, // bInput (FALSE for playback) TRUE, // bShared (TRUE for input/output share memory) TRUE, // bDMA FALSE, // reserved 0) ); // nFrames (0 means use maximum) SV_CHECK( sv_fifo_start(sv, poutput) ); // Loop forever reading frames and displaying. // This will not use 99% CPU since sv_fifo_getbuffer() will block // until a hardware buffer frame is available. int last_res = -1; while (1) { int res; if ((res = read_picture(card, sv, poutput)) != SV_OK) { // Display error only when things change if (res != last_res) { fprintf(stderr, "card %ld: failed to capture video: (%d) %s\n", card, res, res == SV_ERROR_INPUT_VIDEO_NOSIGNAL ? "INPUT_VIDEO_NOSIGNAL" : sv_geterrortext(res)); // reset FIFO if error indicates FIFO problem if (res == SV_ERROR_FIFO_PUTBUFFER) { fprintf(stderr, "SV_ERROR_FIFO_PUTBUFFER: restarting fifo\n"); SV_CHECK( sv_fifo_reset(sv, poutput) ); SV_CHECK( sv_fifo_start(sv, poutput) ); } } last_res = res; usleep( 2 * 1000 * 1000); // 2 second poll continue; } // Only display OK message once if (res != last_res && res == SV_OK) { fprintf(stderr, "card %ld: Video signal OK\n", card); } last_res = res; } return NULL; }
int main(int argc, char ** argv) { sv_handle * sv = NULL; int res = SV_OK; int bsavemode; int bhosttransfer; int bsetbuffersize = 0; int nframes; sv_storageinfo storage; char * buffer; char * buffer_org; int buffersize; int us; int i, j; #ifdef WIN32 LARGE_INTEGER frequency; LARGE_INTEGER timestart; LARGE_INTEGER timeend; QueryPerformanceFrequency(&frequency); #else struct timeval timestart; struct timeval timeend; struct timezone tz; #endif if(argc < 2) { usage(); return -1; } if(!strcmp(argv[1], "load")) { bsavemode = 0; bhosttransfer = 1; } else if(!strcmp(argv[1], "save")) { bsavemode = 1; bhosttransfer = 1; } else if(!strcmp(argv[1], "read")) { bsavemode = 0; bhosttransfer = 0; } else if(!strcmp(argv[1], "write")) { bsavemode = 1; bhosttransfer = 0; } else { usage(); return -1; } #ifndef WIN32 signal(SIGINT, signal_handler); signal(SIGKILL, signal_handler); #endif res = sv_openex(&sv, "", SV_OPENPROGRAM_DEMOPROGRAM, SV_OPENTYPE_DEFAULT, 0, 0); if(res != SV_OK) { printf("dmaspeed: Error '%s' opening video device", sv_geterrortext(res)); return -1; } res = sv_storage_status(sv, 0, NULL, &storage, sizeof(storage), 0); if(bhosttransfer) { buffersize = storage.fieldsize[0] + storage.fieldsize[1]; if(argc >= 3) { nframes = atoi(argv[2]); } else { nframes = 10; } } else { if(argc >= 3) { buffersize = atoi(argv[2]); if(buffersize == 0) { buffersize = strtol(argv[2], NULL, 16); } buffersize = buffersize & ~(ALIGNMENT - 1); bsetbuffersize = 1; } else { buffersize = 0x200000; } nframes = 1; } buffer_org = malloc(buffersize + ALIGNMENT + alignment[0]); buffer = (void*)(((uintptr)buffer_org + ALIGNMENT - 1) & ~(ALIGNMENT-1)); if(buffer == NULL) { fprintf(stderr, "dmaspeed: Failure to allocate video buffer\n"); res = SV_ERROR_MALLOC; } if(res == SV_OK) { if(bhosttransfer) { if(bsavemode) { printf("dmaspeed: frames %d frames, Device -> CPUMemory\n", nframes); } else { printf("dmaspeed: frames %d frames, CPUMemory -> Device\n", nframes); } printf("dmaspeed: framesize %d\n", buffersize); printf("dmaspeed: totalsize %d bytes total\n", nframes * buffersize); #ifdef WIN32 QueryPerformanceCounter(×tart); #else gettimeofday(×tart, &tz); #endif res = sv_transfertest(sv, bsavemode, buffer, buffersize, 0, nframes, storage.storagexsize, storage.storageysize, storage.nbits); #ifdef WIN32 QueryPerformanceCounter(&timeend); #else gettimeofday(&timeend, &tz); #endif if(res == SV_ERROR_PARAMETER) { printf("dmaspeed: returned SV_ERROR_PARAMTER, did you specify more frames than in memory ?\n"); } else if(res == SV_OK) { #ifdef WIN32 #ifdef VERBOSE printf("dmaspeed: frequency %d\n", (int)frequency.QuadPart); printf("dmaspeed: time %d\n", (int)(timeend.QuadPart - timestart.QuadPart)); #endif if(frequency.QuadPart) { us = (int)(((timeend.QuadPart - timestart.QuadPart) * 1000000) / frequency.QuadPart); } else { us = 0; } #else us = (int)((timeend.tv_sec * 1000000 + timeend.tv_usec) - (timestart.tv_sec * 1000000 + timestart.tv_usec)); #ifdef VERBOSE printf("dmaspeed: frequency %d\n", 1000000); printf("dmaspeed: time %d\n", us); #endif #endif if(us) { printf("dmaspeed: %d us %d B/s %d MB/s\n", us, (int)(((int64)nframes * buffersize * 1000000) / us), (int)(((int64)nframes * buffersize) / us)); } else { printf("dmaspeed: Error 0 us execution time ?\n"); } } } else { sv_memory_dma(sv, bsavemode, (void*)((uintptr)buffer), 0x100000, buffersize, NULL); for(i = 0; (res == SV_OK) && (i < arraysize(alignment)); i++) { #ifdef WIN32 QueryPerformanceCounter(×tart); #else gettimeofday(×tart, &tz); #endif if(bsetbuffersize) { res = sv_memory_dma(sv, bsavemode, (void*)((uintptr)buffer+alignment[i]), 0x100000, buffersize, NULL); } else { res = sv_memory_dma(sv, bsavemode, (void*)((uintptr)buffer), 0x100000, buffersize, NULL); } if((res != SV_OK) && (res != SV_ERROR_BUFFER_NOTALIGNED)) { fprintf(stderr, "sv_memory_dma failed: "); sv_errorprint(sv, res); } #ifdef WIN32 QueryPerformanceCounter(&timeend); if(frequency.QuadPart) { us = (int)(((timeend.QuadPart - timestart.QuadPart) * 1000000) / frequency.QuadPart); } else { us = 0; } #else gettimeofday(&timeend, &tz); us = (int)((timeend.tv_sec * 1000000 + timeend.tv_usec) - (timestart.tv_sec * 1000000 + timestart.tv_usec)); #endif resultus[i] = us; } j = i - 1; if(res == SV_ERROR_BUFFER_NOTALIGNED) { res = SV_OK; } if(bsetbuffersize) { for(i = 0; (i < arraysize(alignment)) && (i < j); i++) { if(resultus[i]) { printf("dmaspeed %3d e6/s alignment:%08x/%6d time %d us\n", buffersize / resultus[i], alignment[i], alignment[i], resultus[i]); } else { printf("dmaspeed %3d e6/s alignment:%08x/%6d time %d us ****\n", 0, alignment[i], alignment[i], 0); } } } else { for(us = 0, i = 0; (i < arraysize(alignment)) && (i < j); i++) { us += resultus[i]; } printf("Transferspeed: %3d e6/s %s\n", (int)(buffersize / (us / arraysize(alignment))), bsavemode?"CPUMemory->Device":"Device->CPUMemory"); } } } else { printf("dmaspeed: returned %s\n", sv_geterrortext(res)); } sv_close(sv); free(buffer_org); if(res != SV_OK) { sv_errorprint(sv, res); } if(res == SV_OK) { return 0; } else { return -1; } }
void * loop_in(void * arg) { loop_handle * hd = (loop_handle *) arg; sv_fifo_bufferinfo infosrc; sv_fifo_info status_src; unsigned int lastdrop_src = (unsigned int) ~0; int bufferid; int res = SV_OK; /* // Start the input FIFO. */ res = sv_fifo_start(hd->svsrc, hd->fifosrc); if(res != SV_OK) { printf("sv_fifo_start(src) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } while (hd->running) { /* // >>> Handle input FIFO <<< */ do { res = sv_fifo_getbuffer(hd->svsrc, hd->fifosrc, &hd->bufsrc, NULL, SV_FIFO_FLAG_NODMAADDR | (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0) | (hd->bvideoonly ? SV_FIFO_FLAG_VIDEOONLY : 0) | (hd->baudioonly ? SV_FIFO_FLAG_AUDIOONLY : 0) | (hd->bplayback ? SV_FIFO_FLAG_FLUSH : 0) ); switch(res) { case SV_ERROR_NOCARRIER: case SV_ERROR_INPUT_VIDEO_NOSIGNAL: case SV_ERROR_INPUT_VIDEO_RASTER: case SV_ERROR_INPUT_VIDEO_DETECTING: case SV_ERROR_INPUT_KEY_NOSIGNAL: case SV_ERROR_INPUT_KEY_RASTER: printf("v"); // Inform user about missing video fflush(stdout); res = SV_ACTIVE; break; case SV_ERROR_INPUT_AUDIO_NOAIV: case SV_ERROR_INPUT_AUDIO_NOAESEBU: // In these two cases, getbuffer returned a valid buffer. // So, we can continue without audio. printf("a"); // Inform user about missing audio fflush(stdout); res = SV_OK; break; case SV_ERROR_VSYNCPASSED: printf("NOTE: vsyncpassed possibly caused by signal disconnect\n"); res = SV_ACTIVE; break; default:; } if(res == SV_ACTIVE) { // wait for next vsync and try again sv_fifo_vsyncwait(hd->svsrc, hd->fifosrc); } } while(res == SV_ACTIVE && hd->running); if (res != SV_OK) { printf("sv_fifo_getbuffer(src) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; break; } dvs_mutex_enter(&hd->common.lock); bufferid = get_free_bufferid(hd); dvs_mutex_leave(&hd->common.lock); fill_buffer(hd, TRUE, hd->bufsrc, bufferid); if(hd->banc && (bufferid >= 0)) { //Get list pointer anc_element_t * current_element = &hd->anclist[bufferid]; //If there are valid packets delete them if( current_element->next ) { //Delete all elements in list delete_element( bufferid, current_element->next ); //Set first element to zero memset( current_element, 0, sizeof(anc_element_t) ); } //Try to get anc packets while( res==SV_OK ) { res = sv_fifo_anc( hd->svsrc, hd->fifosrc, hd->bufsrc, ¤t_element->ancbuffer ); if( res == SV_OK ) { current_element->valid = 1; //Log if( hd->bverbose ) { printf("Recorded anc_element. Buffer:%d, DID:0x%x, SDID:0x%x\n", bufferid, current_element->ancbuffer.did, current_element->ancbuffer.sdid ); } //I need to allocate one more packet buffer current_element->next = malloc( sizeof( anc_element_t )); if( current_element->next != 0 ) { //Set all values to zero memset( current_element->next, 0, sizeof( anc_element_t )); //Build the list current_element->next->prev = current_element; current_element = current_element->next; } else { printf("malloc failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } } } // This errorcode shows that no more packets are in the frame if( res == SV_ERROR_NOTAVAILABLE ) { res = SV_OK; } } res = sv_fifo_putbuffer(hd->svsrc, hd->fifosrc, hd->bufsrc, &infosrc); if(res != SV_OK) { printf("sv_fifo_putbuffer(src) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; break; } res = sv_fifo_status(hd->svsrc, hd->fifosrc, &status_src); if(res != SV_OK) { printf("sv_fifo_status(src) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; break; } // Save input delay hd->indelay_info = status_src.recordtick - infosrc.when; hd->inavail_info = status_src.availbuffers; if(hd->bverbose || ((unsigned int)status_src.dropped > lastdrop_src)) { printf("ID %2d - in %06d %d %d %d (%u)\n", bufferid, infosrc.when, status_src.nbuffers, status_src.availbuffers, status_src.dropped - lastdrop_src, infosrc.clock_low); } // Report dropped frames in input FIFO. if((unsigned int)status_src.dropped > lastdrop_src) { printf("input fifo dropped - delay might have changed\n"); } lastdrop_src = status_src.dropped; dvs_mutex_enter(&hd->common.lock); if(bufferid >= 0) { hd->common.inputtick[bufferid] = infosrc.when; } dvs_mutex_leave(&hd->common.lock); /* // Signal that a new input buffer is ready */ dvs_cond_broadcast(&hd->common.ready, &hd->common.lock, FALSE); } res = sv_fifo_stop(hd->svsrc, hd->fifosrc, 0); if(res != SV_OK) { printf("sv_fifo_stop(src) failed %d '%s'\n", res, sv_geterrortext(res)); } hd->exitcode = TRUE; dvs_thread_exit(&hd->exitcode, &hd->finish); return NULL; }
void * loop_out(void * arg) { loop_handle * hd = (loop_handle *) arg; sv_fifo_bufferinfo infodst; sv_fifo_info status_dst; int lastdrop_dst = 0; int displaytick = 0; int res = SV_OK; int bufferid; int fifo_running = FALSE; int flip = 0; dvs_cond_wait(&hd->common.ready, &hd->common.lock, FALSE); while (hd->running) { // check for sync is detected and if genlocked when sync is on the refin while((res == SV_ERROR_SYNC_MISSING) || sv_fifo_sanitycheck(hd->svdst, hd->fifodst) == SV_ERROR_SYNC_MISSING && hd->running) { if(fifo_running) { fifo_running = FALSE; printf("WARNING: lost genlock! Output fifo stopped.\n"); res = sv_fifo_stop(hd->svdst, hd->fifodst, SV_FIFO_FLAG_FLUSH); if(res != SV_OK) { printf("sv_fifo_stop(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } res = sv_fifo_reset(hd->svdst, hd->fifodst); if(res != SV_OK) { printf("sv_fifo_reset(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } } sv_fifo_vsyncwait(hd->svdst, hd->fifodst); } if(!fifo_running) { printf("====> Restarting output fifo. <=====\n"); #if 0 res = sv_fifo_free(hd->svdst, hd->fifodst); if(res != SV_OK) { printf("sv_fifo_reset(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } // Init output FIFO. res = sv_fifo_init(hd->svdst, &hd->fifodst, FALSE, FALSE, TRUE, (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0), 0 ); if(res != SV_OK) { printf("sv_fifo_init(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; return; } res = sv_fifo_sanitylevel(hd->svdst, hd->fifodst, SV_FIFO_SANITY_LEVEL_FATAL, SV_FIFO_SANITY_VERSION_1); if(res != SV_OK) { printf("sv_fifo_sanitylevel(dst) failed %d '%s'\n", res, sv_geterrortext(res)); } #endif res = sv_fifo_startex(hd->svdst, hd->fifodst, &displaytick, NULL, NULL, NULL); if(res != SV_OK) { printf("sv_fifo_start(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } fifo_running = TRUE; } res = sv_fifo_getbuffer(hd->svdst, hd->fifodst, &hd->bufdst, NULL, SV_FIFO_FLAG_NODMAADDR | (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0) | (hd->bvideoonly ? SV_FIFO_FLAG_VIDEOONLY : 0) | (hd->baudioonly ? SV_FIFO_FLAG_AUDIOONLY : 0) | (hd->bfieldbased ? SV_FIFO_FLAG_FIELD : 0) | // enable field-based mode (hd->bvideoonly ? 0 : SV_FIFO_FLAG_SETAUDIOSIZE) | (hd->bottom2top ? SV_FIFO_FLAG_STORAGEMODE : 0) ); switch(res) { case SV_ERROR_SYNC_MISSING: continue; break; default: if(res != SV_OK) { printf("sv_fifo_getbuffer(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } break; } if(hd->bottom2top) { hd->bufdst->storage.storagemode = hd->storage.videomode & (SV_MODE_COLOR_MASK|SV_MODE_NBIT_MASK|SV_MODE_STORAGE_FRAME|SV_MODE_STORAGE_BOTTOM2TOP); hd->bufdst->storage.xsize = hd->storage.storagexsize; hd->bufdst->storage.ysize = hd->storage.storageysize; if(flip) { hd->bufdst->storage.storagemode |= SV_MODE_STORAGE_BOTTOM2TOP; } else { hd->bufdst->storage.storagemode &= ~SV_MODE_STORAGE_BOTTOM2TOP; } flip = (displaytick / 100) & 1; } dvs_mutex_enter(&hd->common.lock); bufferid = get_bufferid(hd, displaytick, hd->ndelay ); dvs_mutex_leave(&hd->common.lock); fill_buffer(hd, FALSE, hd->bufdst, bufferid); if(hd->banc && (bufferid >= 0)) { //Get list anc_element_t * current_element = &hd->anclist[bufferid]; //Try to get anc packets while( current_element->valid ) { current_element->valid = 0; res = sv_fifo_anc( hd->svsrc, hd->fifodst, hd->bufdst, ¤t_element->ancbuffer ); if( res == SV_OK ) { //Log if( hd->bverbose ) { printf("Displayed anc_element. Buffer:%d, DID:0x%x, SDID:0x%x\n", bufferid, current_element->ancbuffer.did, current_element->ancbuffer.sdid ); } if( current_element->next ) { current_element = current_element->next; } } } } res = sv_fifo_putbuffer(hd->svdst, hd->fifodst, hd->bufdst, &infodst); if(res != SV_OK) { printf("sv_fifo_putbuffer(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; break; } // Calculate next output tick. displaytick = infodst.when + hd->vinterlace; res = sv_fifo_status(hd->svdst, hd->fifodst, &status_dst); if(res != SV_OK) { printf("sv_fifo_status(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; break; } // Save output delay hd->outdelay_info = infodst.when - status_dst.displaytick; if(!hd->bverbose) { printf("\rDmaloop: %s in-delay:%2d/%d ticks out-delay:%2d ticks ", (bufferid!=-1) ? "running" : "no buffer", hd->indelay_info, hd->inavail_info, hd->outdelay_info); } if(hd->bverbose || (status_dst.dropped > lastdrop_dst)) { printf("ID %2d - out %06d %d %d %d (%u)\n", bufferid, infodst.when, status_dst.nbuffers, status_dst.availbuffers, status_dst.dropped - lastdrop_dst, infodst.clock_low); } // Report dropped frames in output FIFO. if(status_dst.dropped > lastdrop_dst) { printf("output fifo dropped - delay might have changed\n"); } lastdrop_dst = status_dst.dropped; /* * Wait until I need a new buffer */ if(hd->bfieldbased || hd->bdualsdi) { while(hd->running && ((status_dst.nbuffers - status_dst.availbuffers) > 3/*Fields*/)) { // Wait for next vsync res = sv_fifo_vsyncwait(hd->svdst, hd->fifodst); if(res != SV_OK) { printf("sv_fifo_vsyncwait(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } // Check buffer count res = sv_fifo_status(hd->svdst, hd->fifodst, &status_dst); if(res != SV_OK) { printf("sv_fifo_status(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } } } else { while(hd->running && ((status_dst.nbuffers - status_dst.availbuffers) > 2 /*Frames*/)) { // Wait for next vsync res = sv_fifo_vsyncwait(hd->svdst, hd->fifodst); if(res != SV_OK) { printf("sv_fifo_vsyncwait(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } // Check buffer count res = sv_fifo_status(hd->svdst, hd->fifodst, &status_dst); if(res != SV_OK) { printf("sv_fifo_status(dst) failed %d '%s'\n", res, sv_geterrortext(res)); hd->running = FALSE; } } } } res = sv_fifo_stop(hd->svdst, hd->fifodst, SV_FIFO_FLAG_FLUSH); if(res != SV_OK) { printf("sv_fifo_stop(dst) failed %d '%s'\n", res, sv_geterrortext(res)); } hd->exitcode = TRUE; dvs_thread_exit(&hd->exitcode, &hd->finish); return NULL; }
int loop_init(loop_handle * hd) { sv_fifo_configinfo config; int modesrc = 0; int modedst = 0; int syncmode = 0; int res; int i; char anclayout[1024]; // Open first card. hd->svsrc = sv_open(""); if (hd->svsrc == NULL) { printf("loop_init: sv_open(\"\") failed\n"); loop_exit(hd); return FALSE; } if(hd->buse2cards) { // Open second card. hd->svdst = sv_open("PCI,card:1"); if(hd->svdst == NULL) { printf("loop_init: sv_open(\"PCI.card:1\") failed\n"); loop_exit(hd); return FALSE; } } else { // Use first card for output as well. hd->svdst = hd->svsrc; } // Get current videomode from first card. res = sv_option_get(hd->svsrc, SV_OPTION_VIDEOMODE, &modesrc); if(res != SV_OK) { printf("loop_init: sv_option_get() failed\n"); loop_exit(hd); return FALSE; } // Get current videomode from second card. res = sv_option_get(hd->svdst, SV_OPTION_VIDEOMODE, &modedst); if(res != SV_OK) { printf("loop_init: sv_option_get() failed\n"); loop_exit(hd); return FALSE; } // Compare if both videomodes do match. if((modesrc & SV_MODE_MASK) != (modedst & SV_MODE_MASK)) { printf("loop_init: Raster of source and destination board do not match.\n"); loop_exit(hd); return FALSE; } // Check sync mode res = sv_query(hd->svsrc, SV_QUERY_SYNCMODE, 0, &syncmode); if(res != SV_OK) { printf("loop_init: sv_query(SV_QUERY_SYNCMODE) failed\n"); loop_exit(hd); return FALSE; } if(syncmode == SV_SYNC_INTERNAL) { printf("Error:\tPlease configure another sync mode,\n\tit is not possible to have a stable in to out delay with SV_SYNC_INTERNAL.\n"); loop_exit(hd); return FALSE; } switch(modesrc & SV_MODE_MASK) { case SV_MODE_SMPTE274_47P: case SV_MODE_SMPTE274_48P: case SV_MODE_SMPTE274_50P: case SV_MODE_SMPTE274_59P: case SV_MODE_SMPTE274_60P: case SV_MODE_SMPTE274_71P: case SV_MODE_SMPTE274_72P: hd->bdualsdi = TRUE; break; } // Get information about current raster. res = sv_storage_status(hd->svsrc, 0, NULL, &hd->storage, sizeof(sv_storageinfo), 0); if(res != SV_OK) { printf("loop_init: sv_storage_status() failed = %d '%s'\n", res, sv_geterrortext(res)); } // How many ticks does a frame last? hd->vinterlace = hd->storage.vinterlace; //frame to field correction hd->ndelay = hd->ndelay * hd->storage.vinterlace; //fieldbased correction if(hd->bfieldbased) { hd->vinterlace = 1; } if(hd->banc) { // Disable the fifo ancgenerator because else you will get double packets in loopback res = sv_option_set(hd->svdst, SV_OPTION_ANCGENERATOR, SV_ANCDATA_DISABLE ); if(res != SV_OK) { printf("loop_init: sv_option_set() failed\n"); loop_exit(hd); return FALSE; } } // Init input FIFO. res = sv_fifo_init(hd->svsrc, &hd->fifosrc, TRUE, // input FIFO FALSE, TRUE, // enable DMA mode (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0) | (hd->bfieldbased ? SV_FIFO_FLAG_FIELD : 0), // enable field-based mode 0 // use maximum available buffers ); if(res != SV_OK) { printf("sv_fifo_init(src) failed %d '%s'\n", res, sv_geterrortext(res)); loop_exit(hd); return FALSE; } res = sv_fifo_sanitylevel(hd->svsrc, hd->fifosrc, SV_FIFO_SANITY_LEVEL_FATAL, SV_FIFO_SANITY_VERSION_1); if(res != SV_OK) { printf("sv_fifo_sanitylevel(dst) failed %d '%s'\n", res, sv_geterrortext(res)); } // Init output FIFO. res = sv_fifo_init(hd->svdst, &hd->fifodst, FALSE, // output FIFO FALSE, TRUE, // enable DMA mode (hd->bancstreamer ? SV_FIFO_FLAG_ANC : 0), 0 // use maximum available buffers ); if(res != SV_OK) { printf("sv_fifo_init(dst) failed %d '%s'\n", res, sv_geterrortext(res)); loop_exit(hd); return FALSE; } res = sv_fifo_sanitylevel(hd->svdst, hd->fifodst, SV_FIFO_SANITY_LEVEL_FATAL, SV_FIFO_SANITY_VERSION_1); if(res != SV_OK) { printf("sv_fifo_sanitylevel(dst) failed %d '%s'\n", res, sv_geterrortext(res)); } if(hd->bverbose && hd->bancstreamer) { int required = 0; res = sv_fifo_anclayout(hd->svsrc, hd->fifosrc, anclayout, sizeof(anclayout), &required); if(res == SV_ERROR_BUFFERSIZE) { printf("sv_fifo_anclayout(src) buffer too small (required %d)\n", required); } else if(res != SV_OK) { printf("sv_fifo_anclayout(src) failed %d '%s'\n", res, sv_geterrortext(res)); } else { printf("ANC layout (input):\n%s\n", anclayout); } res = sv_fifo_anclayout(hd->svdst, hd->fifodst, anclayout, sizeof(anclayout), &required); if(res == SV_ERROR_BUFFERSIZE) { printf("sv_fifo_anclayout(dst) buffer too small (required %d)\n", required); } else if(res != SV_OK) { printf("sv_fifo_anclayout(dst) failed %d '%s'\n", res, sv_geterrortext(res)); } else { printf("ANC layout (output):\n%s\n", anclayout); } } // Fetch some information about FIFO buffer sizes. res = sv_fifo_configstatus(hd->svsrc, hd->fifosrc, &config); if(res != SV_OK) { printf("sv_fifo_configstatus(src) failed %d '%s'\n", res, sv_geterrortext(res)); loop_exit(hd); return FALSE; } // Allocate sufficient memory for video and audio data. for(i = 0; i < MAX_ID; i++) { memset( &hd->anclist[i], 0, sizeof(hd->anclist[i]) ); hd->livebuffer_org[i] = malloc(config.vbuffersize + config.abuffersize + (config.dmaalignment-1)); hd->livebuffer[i] = (char *)((uintptr)(hd->livebuffer_org[i] + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1)); if(!hd->livebuffer_org[i]) { printf("malloc(%d) livebuffer %d failed\n", config.vbuffersize + config.abuffersize + (config.dmaalignment-1), i); loop_exit(hd); return FALSE; } if(config.ancbuffersize && hd->bancstreamer) { hd->ancbuffer_org[i] = malloc(config.ancbuffersize + (config.dmaalignment-1)); hd->ancbuffer[i] = (char *)((uintptr)(hd->ancbuffer_org[i] + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1)); if(!hd->ancbuffer_org[i]) { printf("malloc(%d) ancbuffer %d failed\n", config.ancbuffersize + (config.dmaalignment-1), i); loop_exit(hd); return FALSE; } } } // Allocate sufficient memory for video and audio data. hd->blackbuffer_org = malloc(config.vbuffersize + config.abuffersize + (config.dmaalignment-1)); hd->blackbuffer = (char *)((uintptr)(hd->blackbuffer_org + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1)); if(!hd->blackbuffer_org) { printf("malloc(%d) blackbuffer failed\n", config.vbuffersize + config.abuffersize + (config.dmaalignment-1)); loop_exit(hd); return FALSE; } memset(hd->blackbuffer_org, 0, config.vbuffersize + config.abuffersize + (config.dmaalignment-1)); // Allocate sufficient memory for video and audio data. hd->nobuffer_org = malloc(config.vbuffersize + config.abuffersize + (config.dmaalignment-1)); hd->nobuffer = (char *)((uintptr)(hd->nobuffer_org + (config.dmaalignment-1)) & ~(uintptr)(config.dmaalignment-1)); if(!hd->nobuffer_org) { printf("malloc(%d) nobuffer failed\n", config.vbuffersize + config.abuffersize + (config.dmaalignment-1)); loop_exit(hd); return FALSE; } memset(hd->nobuffer_org, 0xff, config.vbuffersize + config.abuffersize + (config.dmaalignment-1)); dvs_mutex_init(&hd->common.lock); dvs_cond_init(&hd->common.ready); return TRUE; }