int main (int argc, char ** argv) { int n, max_cards = 1; time_t now; struct tm *tm_now; now = time ( NULL ); tm_now = localtime ( &now ); // process command-line args for (n = 1; n < argc; n++) { if (strcmp(argv[n], "-v") == 0) { verbose++; } else if (strcmp(argv[n], "-q") == 0) { verbose = 0; } else if (strcmp(argv[n], "-n") == 0) { no_audio = 1; } else if (strcmp(argv[n], "-l") == 0) { loop = 1; } else if (strcmp(argv[n], "-in") == 0) { if (sscanf(argv[n+1], "%"PRIu64, &frame_inpoint) != 1) { fprintf(stderr, "-in requires integer number of frames\n"); return 1; } n++; } else if (strcmp(argv[n], "-out") == 0) { if (sscanf(argv[n+1], "%"PRIu64, &frame_outpoint) != 1) { fprintf(stderr, "-out requires integer number of frames\n"); return 1; } n++; } else if (strcmp(argv[n], "-black") == 0) { if (sscanf(argv[n+1], "%u", &black_frames) != 1) { fprintf(stderr, "-black requires integer number of frames\n"); return 1; } n++; } else if (strcmp(argv[n], "-h") == 0 || strcmp(argv[n], "--help") == 0) { usage_exit(); } else if (strcmp(argv[n], "-t") == 0) { if (sscanf(argv[n+1], "%d", &timecode) != 1) { fprintf(stderr, "-t requires integer timecode\n"); return 1; } n++; } // Set video and audio files else { if (! video_file) video_file = argv[n]; else if (! audio12_file) audio12_file = argv[n]; else if (! audio34_file) audio34_file = argv[n]; } } if (no_audio && !video_file) usage_exit(); if (!no_audio && (!audio12_file || !audio34_file)) usage_exit(); ////////////////////////////////////////////////////// // Attempt to open all sv cards // // card specified by string of form "PCI,card=n" where n = 0,1,2,3 // int card; for (card = 0; card < max_cards; card++) { sv_info status_info; char card_str[20] = {0}; snprintf(card_str, sizeof(card_str)-1, "PCI,card=%d", card); int res = sv_openex(&a_sv[card], card_str, SV_OPENPROGRAM_DEMOPROGRAM, SV_OPENTYPE_MASK_DEFAULT, 0, 0); if (res != SV_OK) { // typical reasons include: // SV_ERROR_DEVICENOTFOUND // SV_ERROR_DEVICEINUSE fprintf(stderr, "card %d: %s\n", card, sv_geterrortext(res)); continue; } sv_status( a_sv[card], &status_info); printf("card[%d] frame is %dx%d, assuming input UYVY matches\n", card, status_info.xsize, status_info.ysize); video_size = status_info.xsize * status_info.ysize *2; } // FIXME - this could be calculated correctly by using a struct for example element_size = video_size // video frame + 0x8000; // size of internal structure of dvs dma transfer // for 4 channels. This is greater than 1920 * 4 * 4 // so we use the last 4 bytes for timecode audio_offset = video_size; // Open sample video and audio files if ((fp_video = fopen(video_file, "rb")) == NULL) { perror("fopen input video file"); return 0; } if (! no_audio) { if ((fp_audio12 = fopen(audio12_file, "rb")) == NULL) { perror("fopen input audio 1,2 file"); return 0; } fseek(fp_audio12, 44, SEEK_SET); // skip WAV header if ((fp_audio34 = fopen(audio34_file, "rb")) == NULL) { perror("fopen input audio 3,4 file"); return 0; } fseek(fp_audio34, 44, SEEK_SET); // skip WAV header } // skip input frames if specified if (frame_inpoint) { fseeko(fp_video, frame_inpoint * video_size, SEEK_SET); current_video_frame = frame_inpoint; if (! no_audio) { int audio_size = 1920*2*4; fseeko(fp_audio12, frame_inpoint * audio_size, SEEK_SET); fseeko(fp_audio34, frame_inpoint * audio_size, SEEK_SET); } } if (black_frames > 0) { black_frame_buf = (uint8_t*)malloc(video_size); // initialise black frame buffer with 0x80108010 (UYVY black) int i; for (i = 0; i < video_size; i+= 4) { black_frame_buf[i+0] = 0x80; black_frame_buf[i+1] = 0x10; black_frame_buf[i+2] = 0x80; black_frame_buf[i+3] = 0x10; } } // Loop forever reading from file, writing to sv fifo card = 0; sdi_monitor((void *)(long)card); return 0; }
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; } }