void openlase_trace(t_jit_openlase_trace *x, int width, int height, uint8_t *base, unsigned bytesperrow) { //float vidtime = 0; //int inf=0; int bg_white = -1; //float time = 0; float ftime; //int frames = 0; OLTraceResult result; memset(&result, 0, sizeof(result)); int thresh; int obj; int bsum = 0; int c; int thresh_dark; int thresh_light; int sw_dark; int sw_light; int decimate = x->decimate; int edge_off; thresh_dark = 60; thresh_light = 160; sw_dark = 100; sw_light = 256; //decimate = 1; //decimate = 2; edge_off = 0; for (c=edge_off; c<(width-edge_off); c++) { bsum += base[c+edge_off*bytesperrow]; bsum += base[c+(height-edge_off-1)*bytesperrow]; } for (c=edge_off; c<(height-edge_off); c++) { bsum += base[edge_off+c*bytesperrow]; bsum += base[(c+1)*bytesperrow-1-edge_off]; } bsum /= (2*(width+height)); if (bg_white == -1) bg_white = bsum > 128; if (bg_white && bsum < sw_dark) bg_white = 0; if (!bg_white && bsum > sw_light) bg_white = 1; if (bg_white) thresh = thresh_light; else thresh = thresh_dark; x->tparams.threshold = thresh; olTraceReInit(x->trace_ctx, &x->tparams); olTraceFree(&result); obj = olTrace(x->trace_ctx, base, bytesperrow, &result); //do { int i, j; for (i = 0; i < result.count; i++) { OLTraceObject *o = &result.objects[i]; olBegin(OL_POINTS); OLTracePoint *p = o->points; for (j = 0; j < o->count; j++) { if (j % decimate == 0) olVertex(p->x, p->y, C_WHITE); p++; } olEnd(); } ftime = olRenderFrame(200); if (0) { OLFrameInfo info; char msg[256]; olGetFrameInfo(&info); sprintf(msg, "%d:%d Thr %3d Bg %3d Pts %4d", width, height, thresh, bsum, info.points); object_post((t_object *)x, msg); } //frames++; //time += ftime; //printf("Frame time: %.04f, Cur FPS:%6.02f, Avg FPS:%6.02f, Drift: %7.4f, " // "In %4d, Out %4d Thr %3d Bg %3d Pts %4d", // ftime, 1/ftime, frames/time, time-vidtime, // inf, frames, thresh, bsum, info.points); //if (info.resampled_points) // printf(" Rp %4d Bp %4d", info.resampled_points, info.resampled_blacks); //if (info.padding_points) // printf(" Pad %4d", info.padding_points); //printf("\n"); //} while ((time+frametime) < vidtime); olTraceFree(&result); }
int main (int argc, char *argv[]) { OLRenderParams params; AVFrame *frame; int i; // Register all formats and codecs av_register_all(); memset(¶ms, 0, sizeof params); params.rate = 48000; params.on_speed = 2.0/100.0; params.off_speed = 2.0/15.0; params.start_wait = 8; params.end_wait = 3; params.snap = 1/120.0; params.render_flags = RENDER_GRAYSCALE; params.min_length = 4; params.start_dwell = 2; params.end_dwell = 2; float snap_pix = 3; float aspect = 0; float framerate = 0; float overscan = 0; int thresh_dark = 60; int thresh_light = 160; int sw_dark = 100; int sw_light = 256; int decimate = 2; int edge_off = 0; int optchar; OLTraceParams tparams = { .mode = OL_TRACE_THRESHOLD, .sigma = 0, .threshold2 = 50 }; while ((optchar = getopt(argc, argv, "hct:T:b:w:B:W:O:d:m:S:E:D:g:s:p:a:r:R:o:v:")) != -1) { switch (optchar) { case 'h': case '?': usage(argv[0]); return 0; case 'c': tparams.mode = OL_TRACE_CANNY; tparams.sigma = 1; break; case 't': thresh_dark = thresh_light = atoi(optarg); break; case 'T': tparams.threshold2 = atoi(optarg); break; case 'b': thresh_dark = atoi(optarg); break; case 'w': thresh_light = atoi(optarg); break; case 'B': sw_dark = atoi(optarg); break; case 'W': sw_light = atoi(optarg); break; case 'O': edge_off = atoi(optarg); break; case 'd': decimate = atoi(optarg); break; case 'm': params.min_length = atoi(optarg); break; case 'S': params.start_wait = atoi(optarg); break; case 'E': params.end_wait = atoi(optarg); break; case 'D': params.start_dwell = atoi(optarg); params.end_dwell = atoi(optarg); break; case 'g': tparams.sigma = atof(optarg); break; case 's': params.off_speed = 2.0f/atof(optarg); break; case 'p': snap_pix = atof(optarg); break; case 'a': aspect = atof(optarg); break; case 'r': framerate = atof(optarg); break; case 'R': params.max_framelen = params.rate/atof(optarg); break; case 'o': overscan = atof(optarg); break; case 'v': volume = atof(optarg); break; } } if (optind == argc) { usage(argv[0]); return 1; } if (av_vid_init(argv[optind]) != 0) { printf("Video open/init failed\n"); return 1; } if (av_aud_init(argv[optind]) != 0) { printf("Audio open/init failed\n"); return 1; } if(olInit(FRAMES_BUF, 300000) < 0) { printf("OpenLase init failed\n"); return 1; } if (aspect == 0) aspect = pCodecCtx->width / (float)pCodecCtx->height; if (framerate == 0) framerate = (float)pFormatCtx->streams[videoStream]->r_frame_rate.num / (float)pFormatCtx->streams[videoStream]->r_frame_rate.den; float iaspect = 1/aspect; if (aspect > 1) { olSetScissor(-1, -iaspect, 1, iaspect); olScale(1, iaspect); } else { olSetScissor(-aspect, -1, aspect, 1); olScale(aspect, 1); } printf("Aspect is %f %f\n", aspect, iaspect); printf("Overscan is %f\n", overscan); olScale(1+overscan, 1+overscan); olTranslate(-1.0f, 1.0f); olScale(2.0f/pCodecCtx->width, -2.0f/pCodecCtx->height); int maxd = pCodecCtx->width > pCodecCtx->height ? pCodecCtx->width : pCodecCtx->height; params.snap = (snap_pix*2.0)/(float)maxd; float frametime = 1.0f/framerate; printf("Framerate: %f (%fs per frame)\n", framerate, frametime); olSetAudioCallback(moreaudio); olSetRenderParams(¶ms); float vidtime = 0; int inf=0; int bg_white = -1; float time = 0; float ftime; int frames = 0; OLFrameInfo info; OLTraceCtx *trace_ctx; OLTraceResult result; memset(&result, 0, sizeof(result)); tparams.width = pCodecCtx->width, tparams.height = pCodecCtx->height, olTraceInit(&trace_ctx, &tparams); while(GetNextFrame(pFormatCtx, pCodecCtx, videoStream, &frame)) { if (inf == 0) printf("Frame stride: %d\n", frame->linesize[0]); inf+=1; if (vidtime < time) { vidtime += frametime; printf("Frame skip!\n"); continue; } vidtime += frametime; int thresh; int obj; int bsum = 0; int c; for (c=edge_off; c<(pCodecCtx->width-edge_off); c++) { bsum += frame->data[0][c+edge_off*frame->linesize[0]]; bsum += frame->data[0][c+(pCodecCtx->height-edge_off-1)*frame->linesize[0]]; } for (c=edge_off; c<(pCodecCtx->height-edge_off); c++) { bsum += frame->data[0][edge_off+c*frame->linesize[0]]; bsum += frame->data[0][(c+1)*frame->linesize[0]-1-edge_off]; } bsum /= (2*(pCodecCtx->width+pCodecCtx->height)); if (bg_white == -1) bg_white = bsum > 128; if (bg_white && bsum < sw_dark) bg_white = 0; if (!bg_white && bsum > sw_light) bg_white = 1; if (bg_white) thresh = thresh_light; else thresh = thresh_dark; tparams.threshold = thresh; olTraceReInit(trace_ctx, &tparams); olTraceFree(&result); obj = olTrace(trace_ctx, frame->data[0], frame->linesize[0], &result); do { int i, j; for (i = 0; i < result.count; i++) { OLTraceObject *o = &result.objects[i]; olBegin(OL_POINTS); OLTracePoint *p = o->points; for (j = 0; j < o->count; j++) { if (j % decimate == 0) olVertex(p->x, p->y, C_WHITE); p++; } olEnd(); } ftime = olRenderFrame(200); olGetFrameInfo(&info); frames++; time += ftime; printf("Frame time: %.04f, Cur FPS:%6.02f, Avg FPS:%6.02f, Drift: %7.4f, " "In %4d, Out %4d Thr %3d Bg %3d Pts %4d", ftime, 1/ftime, frames/time, time-vidtime, inf, frames, thresh, bsum, info.points); if (info.resampled_points) printf(" Rp %4d Bp %4d", info.resampled_points, info.resampled_blacks); if (info.padding_points) printf(" Pad %4d", info.padding_points); printf("\n"); } while ((time+frametime) < vidtime); } olTraceDeinit(trace_ctx); for(i=0;i<FRAMES_BUF;i++) olRenderFrame(200); olShutdown(); av_deinit(); exit (0); }
void *display_thread(void *arg) { PlayerCtx *ctx = arg; int i; OLRenderParams params; memset(¶ms, 0, sizeof params); params.rate = 48000; params.on_speed = 2.0/100.0; params.off_speed = 2.0/15.0; params.start_wait = 8; params.end_wait = 3; params.snap = 1/120.0; params.render_flags = RENDER_GRAYSCALE; params.min_length = 20; params.start_dwell = 2; params.end_dwell = 2; params.max_framelen = 48000/20.0; if(olInit(OL_FRAMES_BUF, 300000) < 0) { printf("OpenLase init failed\n"); return NULL; } float aspect = ctx->width / (float)ctx->height; float sample_aspect = av_q2d(ctx->v_stream->sample_aspect_ratio); if (sample_aspect != 0) aspect *= sample_aspect; printf("Aspect: %f\n", aspect); float iaspect = 1/aspect; int maxd = ctx->width > ctx->height ? ctx->width : ctx->height; int mind = ctx->width < ctx->height ? ctx->width : ctx->height; g_ctx = ctx; olSetAudioCallback(get_audio); olSetRenderParams(¶ms); OLTraceCtx *trace_ctx; OLTraceParams tparams; OLTraceResult result; memset(&result, 0, sizeof(result)); ctx->settings_changed = 1; tparams.sigma = ctx->settings.blur / 100.0; if (ctx->settings.canny) tparams.mode = OL_TRACE_CANNY; else tparams.mode = OL_TRACE_THRESHOLD; tparams.width = ctx->width; tparams.height = ctx->height; printf("Resolution: %dx%d\n", ctx->width, ctx->height); olTraceInit(&trace_ctx, &tparams); VideoFrame *last = NULL; pthread_mutex_lock(&ctx->display_mode_mutex); DisplayMode display_mode = ctx->display_mode; pthread_mutex_unlock(&ctx->display_mode_mutex); int inf = 0; int bg_white = -1; float time = 0; int frames = 0; while (display_mode != STOP) { pthread_mutex_lock(&ctx->settings_mutex); PlayerSettings settings = ctx->settings; int settings_changed = ctx->settings_changed; ctx->settings_changed = 0; pthread_mutex_unlock(&ctx->settings_mutex); if (ctx->audio_idx == -1) { drop_all_video(ctx); next_video_frame(ctx); } params.min_length = settings.minsize; params.end_dwell = params.start_dwell = settings.dwell; params.off_speed = settings.offspeed * 0.002; params.snap = (settings.snap*2.0)/(float)maxd; params.start_wait = settings.startwait; params.end_wait = settings.endwait; if (settings.minrate == 0) params.max_framelen = 0; else params.max_framelen = params.rate / settings.minrate; olSetRenderParams(¶ms); olLoadIdentity(); if (aspect > 1) { olSetScissor(-1, -iaspect, 1, iaspect); olScale(1, iaspect); } else { olSetScissor(-aspect, -1, aspect, 1); olScale(aspect, 1); } olScale(1 + settings.overscan/100.0, 1 + settings.overscan/100.0); olTranslate(-1.0f, 1.0f); olScale(2.0f/ctx->width, -2.0f/ctx->height); if (!ctx->cur_frame || ctx->cur_frame->seekid < 0) { printf("Dummy frame\n"); float ftime = olRenderFrame(80); pthread_mutex_lock(&ctx->display_mode_mutex); display_mode = ctx->display_mode; pthread_mutex_unlock(&ctx->display_mode_mutex); if (ctx->cur_frame && ctx->cur_frame->seekid < 0) deliver_event(ctx, time, ftime, frames, 1); else deliver_event(ctx, time, ftime, frames, 0); continue; } if (last != ctx->cur_frame || settings_changed) { tparams.sigma = settings.blur / 100.0; if (settings.canny) { tparams.mode = OL_TRACE_CANNY; tparams.threshold = settings.threshold; tparams.threshold2 = settings.threshold2; bg_white = -1; } else { tparams.mode = OL_TRACE_THRESHOLD; if (settings.splitthreshold) { int edge_off = mind * settings.offset / 100; int bsum = 0; int cnt = 0; int c; for (c = edge_off; c < (ctx->width-edge_off); c++) { bsum += ctx->cur_frame->data[c+edge_off*ctx->cur_frame->stride]; bsum += ctx->cur_frame->data[c+(ctx->height-edge_off-1)*ctx->cur_frame->stride]; cnt += 2; } for (c = edge_off; c < (ctx->height-edge_off); c++) { bsum += ctx->cur_frame->data[edge_off+ctx->cur_frame->stride]; bsum += ctx->cur_frame->data[(c+1)*ctx->cur_frame->stride-1-edge_off]; cnt += 2; } bsum /= cnt; if (bg_white == -1) bg_white = bsum > ((settings.darkval + settings.lightval)/2); if (bg_white && bsum < settings.darkval) bg_white = 0; if (!bg_white && bsum > settings.lightval) bg_white = 1; if (bg_white) tparams.threshold = settings.threshold2; else tparams.threshold = settings.threshold; } else { tparams.threshold = settings.threshold; } } olTraceReInit(trace_ctx, &tparams); olTraceFree(&result); printf("Trace\n"); olTrace(trace_ctx, ctx->cur_frame->data, ctx->cur_frame->stride, &result); printf("Trace done\n"); inf++; last = ctx->cur_frame; } int i, j; for (i = 0; i < result.count; i++) { OLTraceObject *o = &result.objects[i]; olBegin(OL_POINTS); OLTracePoint *p = o->points; for (j = 0; j < o->count; j++) { if (j % settings.decimation == 0) olVertex(p->x, p->y, C_WHITE); p++; } olEnd(); } float ftime = olRenderFrame(80); OLFrameInfo info; olGetFrameInfo(&info); frames++; time += ftime; printf("Frame time: %.04f, Cur FPS:%6.02f, Avg FPS:%6.02f, Drift: %7.4f, " "In %4d, Out %4d Thr %3d/%3d Bg %3d Pts %4d", ftime, 1/ftime, frames/time, 0.0, inf, frames, tparams.threshold, tparams.threshold2, 0, info.points); if (info.resampled_points) printf(" Rp %4d Bp %4d", info.resampled_points, info.resampled_blacks); if (info.padding_points) printf(" Pad %4d", info.padding_points); printf("\n"); deliver_event(ctx, time, ftime, frames, 0); pthread_mutex_lock(&ctx->display_mode_mutex); display_mode = ctx->display_mode; pthread_mutex_unlock(&ctx->display_mode_mutex); } olTraceDeinit(trace_ctx); for(i = 0; i < OL_FRAMES_BUF; i++) olRenderFrame(80); olShutdown(); return NULL; }