// 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; }
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; }