static void create( int width, int height ) { SDL_FreeSurface( screen ); if( Vis::pluginIsGL ) { const SDL_VideoInfo *videoinfo = SDL_GetVideoInfo(); if( videoinfo == NULL ) { std::cerr << "CRITICAL: Could not get video info\n"; std::exit( -2 ); } int videoflags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_RESIZABLE; videoflags |= videoinfo->hw_available ? SDL_HWSURFACE : SDL_SWSURFACE; if( videoinfo->blit_hw ) videoflags |= SDL_HWACCEL; SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); screen = SDL_SetVideoMode( width, height, 16, videoflags ); } else screen = SDL_SetVideoMode( width, height, Vis::video->bpp * 8, SDL_RESIZABLE ); visual_video_set_buffer( Vis::video, screen->pixels ); visual_video_set_pitch( Vis::video, screen->pitch ); }
int visual_video_init (VisVideo *video) { visual_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL); /* Do the VisObject initialization */ visual_object_clear (VISUAL_OBJECT (video)); visual_object_set_dtor (VISUAL_OBJECT (video), video_dtor); visual_object_set_allocated (VISUAL_OBJECT (video), FALSE); /* Reset the VisVideo data */ video->buffer = visual_buffer_new (); video->pixel_rows = NULL; visual_video_set_attributes (video, 0, 0, 0, VISUAL_VIDEO_DEPTH_NONE); visual_video_set_buffer (video, NULL); visual_video_set_palette (video, NULL); video->parent = NULL; video->rect = visual_rectangle_new_empty (); /* Composite control */ video->compositetype = VISUAL_VIDEO_COMPOSITE_TYPE_SRC; /* Colors */ video->colorkey = visual_color_new (); return VISUAL_OK; }
static void draw_frame_ov_lv(void * data, gavl_video_frame_t * frame) { lv_priv_t * priv; priv = (lv_priv_t*)data; visual_video_set_buffer(priv->video, frame->planes[0]); visual_video_set_pitch(priv->video, frame->strides[0]); visual_actor_run(priv->actor, priv->audio); priv->have_audio = 0; }
/** LibVisualBitmapView.renderVisual() */ JNIEXPORT void JNICALL Java_org_libvisual_android_LibVisualBitmapView_renderVisual(JNIEnv * env, jobject obj, jobject bitmap, jint bin, jint video) { VisBin *b = (VisBin *) bin; VisVideo *bvideo = (VisVideo *) video; if(!visual_is_initialized() || !bvideo || !b || !b->input || !b->actor || !b->actvideo) { LOGE("Not initialized properly"); return; } /* start fps timing */ fps_startFrame(&_v.fps); /* run libvisual pipeline */ visual_bin_run(b); /* lock bitmap for drawing */ int ret; void *pixels; if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); } /* set buffer to pixels */ visual_video_set_buffer(bvideo, pixels); /* depth transform */ visual_video_convert_depth(bvideo, b->actvideo); /* unlock bitmap */ AndroidBitmap_unlockPixels(env, bitmap); /* stop fps timing */ fps_endFrame(&_v.fps); }
static int native_getvideo (SADisplay *display, VisVideo *screen) { SDLNative *native = SDL_NATIVE (display->native); SDL_Surface *sdlscreen = native->screen; if (native->requested_depth == VISUAL_VIDEO_DEPTH_GL) visual_video_set_depth (screen, VISUAL_VIDEO_DEPTH_GL); else visual_video_set_depth (screen, visual_video_depth_enum_from_value (sdlscreen->format->BitsPerPixel)); visual_video_set_dimension (screen, sdlscreen->w, sdlscreen->h); visual_video_set_pitch (screen, sdlscreen->pitch); visual_video_set_buffer (screen, sdlscreen->pixels); return 0; }
static uint render() { /* On depth change */ if( visual_bin_depth_changed( bin ) ) { SDL::lock(); pluginIsGL = (visual_bin_get_depth( bin ) == VISUAL_VIDEO_DEPTH_GL); SDL::create( SDL::screen->w, SDL::screen->h ); visual_bin_sync( bin, true ); SDL::unlock(); } long ticks = -SDL_GetTicks(); if( pluginIsGL ) { visual_bin_run( bin ); SDL_GL_SwapBuffers(); } else { SDL::lock(); visual_video_set_buffer( video, SDL::screen->pixels ); visual_bin_run( bin ); SDL::unlock(); Vis::pal = visual_bin_get_palette( bin ); SDL::set_pal(); SDL_Flip( SDL::screen ); } ticks += SDL_GetTicks(); return ticks; }
/* Main stuff */ int main (int argc, char *argv[]) { int width = 1000, height = 600; int i, j; int freeze = 0; int depthflag = 0; int alpha = 190; int xoff = 0, yoff = -90; int sxsize = 1000; int sysize = 700; int interpol = VISUAL_VIDEO_SCALE_NEAREST; int frames = 0; VisTime start, end; bpp = 4; sdl_init (width, height); scrbuf = malloc (screen->pitch * screen->h); memset (scrbuf, 0, screen->pitch * screen->h); SDL_Event event; visual_init (&argc, &argv); if (argc > 1) actor = visual_actor_new (argv[1]); else actor = visual_actor_new ("corona"); visual_actor_realize (actor); video = visual_video_new (); if (argc > 2) video = visual_bitmap_load_new_video (argv[2]); else video = visual_bitmap_load_new_video ("bg.bmp"); actvid = visual_video_new (); visual_actor_set_video (actor, actvid); visual_video_set_depth (actvid, visual_video_depth_get_highest (visual_actor_get_supported_depth (actor))); visual_video_set_dimension (actvid, width, height); visual_video_allocate_buffer (actvid); visual_actor_video_negotiate (actor, 0, FALSE, FALSE); video32 = visual_video_new (); visual_video_set_depth (video32, VISUAL_VIDEO_DEPTH_32BIT); visual_video_set_dimension (video32, video->width, video->height); visual_video_allocate_buffer (video32); scalevid = visual_video_new (); visual_video_set_depth (scalevid, VISUAL_VIDEO_DEPTH_32BIT); visual_video_set_dimension (scalevid, sxsize, sysize); visual_video_allocate_buffer (scalevid); sdlvid = visual_video_new (); visual_video_set_depth (sdlvid, VISUAL_VIDEO_DEPTH_32BIT); visual_video_set_dimension (sdlvid, screen->w, screen->h); visual_video_set_pitch (sdlvid, screen->pitch); visual_video_set_buffer (sdlvid, scrbuf); input = visual_input_new ("xmms2"); visual_input_realize (input); SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); visual_time_get (&start); while (1) { visual_input_run (input); visual_actor_run (actor, input->audio); /* place on screen */ // visual_video_blit_overlay (sdlvid, video, 0, 0, FALSE); if (sxsize < 0) sxsize = 0; if (sysize < 0) sysize = 0; if (sxsize != scalevid->width || sysize != scalevid->height) { visual_video_set_dimension (scalevid, sxsize, sysize); visual_video_allocate_buffer (scalevid); } visual_video_depth_transform (video32, video); // visual_video_alpha_fill (sdlvid, 0); // visual_video_alpha_fill (video32, alpha); // visual_video_alpha_color (video32, 0, 0, 0, 255); do_alpha (video32, alpha); visual_video_scale (scalevid, video32, interpol); visual_video_blit_overlay (sdlvid, actvid, 0, 0, FALSE); visual_video_blit_overlay (sdlvid, scalevid, xoff, yoff, TRUE); sdl_draw_buf (); frames++; while (SDL_PollEvent (&event)) { switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_F11: SDL_WM_ToggleFullScreen (screen); break; case SDLK_UP: yoff -= 10; break; case SDLK_DOWN: yoff += 10; break; case SDLK_LEFT: xoff -= 10; break; case SDLK_RIGHT: xoff += 10; break; case SDLK_q: sysize -= 10; break; case SDLK_a: sysize += 10; break; case SDLK_z: sxsize -= 10; break; case SDLK_x: sxsize += 10; break; case SDLK_i: if (interpol == VISUAL_VIDEO_SCALE_NEAREST) interpol = VISUAL_VIDEO_SCALE_BILINEAR; else interpol = VISUAL_VIDEO_SCALE_NEAREST; break; case SDLK_o: alpha -= 8; if (alpha < 0) alpha = 0; break; case SDLK_p: alpha += 8; if (alpha > 255) alpha = 255; break; case SDLK_ESCAPE: goto out; break; } break; case SDL_VIDEORESIZE: sdl_size_request (event.resize.w, event.resize.h); break; case SDL_QUIT: goto out; break; } } } out: visual_time_get (&end); VisTime diff; visual_time_difference (&diff, &start, &end); printf ("Ran: %d:%d, drawn %d frames\n", diff.tv_sec, diff.tv_usec, frames); SDL_Quit (); }
int visual_bin_sync (VisBin *bin, int noevent) { VisVideo *video; VisVideo *actvideo; visual_log_return_val_if_fail (bin != NULL, -1); visual_log (VISUAL_LOG_DEBUG, "starting sync"); /* Sync the actor regarding morph */ if (bin->morphing == TRUE && bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH && bin->actvideo->depth != VISUAL_VIDEO_DEPTH_GL && bin->depthfromGL != TRUE) { visual_morph_set_video (bin->morph, bin->actvideo); video = bin->privvid; if (video == NULL) { visual_log (VISUAL_LOG_DEBUG, "Private video data NULL"); return -1; } visual_video_free_buffer (video); visual_video_clone (video, bin->actvideo); visual_log (VISUAL_LOG_DEBUG, "pitches actvideo %d, new video %d", bin->actvideo->pitch, video->pitch); visual_log (VISUAL_LOG_DEBUG, "phase1 bin->privvid %p", bin->privvid); if (bin->actmorph->video->depth == VISUAL_VIDEO_DEPTH_GL) { visual_video_set_buffer (video, NULL); video = bin->actvideo; } else visual_video_allocate_buffer (video); visual_log (VISUAL_LOG_DEBUG, "phase2"); } else { video = bin->actvideo; if (video == NULL) { visual_log (VISUAL_LOG_DEBUG, "Actor video is NULL"); return -1; } visual_log (VISUAL_LOG_DEBUG, "setting new video from actvideo %d %d", video->depth, video->bpp); } /* Main actor */ /* visual_actor_realize (bin->actor); */ visual_actor_set_video (bin->actor, video); visual_log (VISUAL_LOG_DEBUG, "one last video pitch check %d depth old %d forcedmain %d noevent %d", video->pitch, bin->depthold, bin->depthforcedmain, noevent); if (bin->managed == TRUE) { if (bin->depthold == VISUAL_VIDEO_DEPTH_GL) visual_actor_video_negotiate (bin->actor, bin->depthforcedmain, FALSE, TRUE); else visual_actor_video_negotiate (bin->actor, bin->depthforcedmain, noevent, TRUE); } else { if (bin->depthold == VISUAL_VIDEO_DEPTH_GL) visual_actor_video_negotiate (bin->actor, 0, FALSE, TRUE); else visual_actor_video_negotiate (bin->actor, 0, noevent, FALSE); } visual_log (VISUAL_LOG_DEBUG, "pitch after main actor negotiate %d", video->pitch); /* Morphing actor */ if (bin->actmorphmanaged == TRUE && bin->morphing == TRUE && bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH) { actvideo = bin->actmorphvideo; if (actvideo == NULL) { visual_log (VISUAL_LOG_DEBUG, "Morph video is NULL"); return -1; } visual_video_free_buffer (actvideo); visual_video_clone (actvideo, video); if (bin->actor->video->depth != VISUAL_VIDEO_DEPTH_GL) visual_video_allocate_buffer (actvideo); visual_actor_realize (bin->actmorph); visual_log (VISUAL_LOG_DEBUG, "phase3 pitch of real framebuffer %d", bin->actvideo->pitch); if (bin->actmorphmanaged == TRUE) visual_actor_video_negotiate (bin->actmorph, bin->depthforced, FALSE, TRUE); else visual_actor_video_negotiate (bin->actmorph, 0, FALSE, FALSE); } visual_log (VISUAL_LOG_DEBUG, "end sync function"); return 0; }
static GstFlowReturn gst_visual_chain (GstPad * pad, GstBuffer * buffer) { GstBuffer *outbuf = NULL; guint i; GstVisual *visual = GST_VISUAL (gst_pad_get_parent (pad)); GstFlowReturn ret = GST_FLOW_OK; guint avail; GST_DEBUG_OBJECT (visual, "chain function called"); /* If we don't have an output format yet, preallocate a buffer to try and * set one */ if (GST_PAD_CAPS (visual->srcpad) == NULL) { ret = get_buffer (visual, &outbuf); if (ret != GST_FLOW_OK) { gst_buffer_unref (buffer); goto beach; } } /* resync on DISCONT */ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { gst_adapter_clear (visual->adapter); } GST_DEBUG_OBJECT (visual, "Input buffer has %d samples, time=%" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer) / visual->bps, GST_BUFFER_TIMESTAMP (buffer)); gst_adapter_push (visual->adapter, buffer); while (TRUE) { gboolean need_skip; const guint16 *data; guint64 dist, timestamp; GST_DEBUG_OBJECT (visual, "processing buffer"); avail = gst_adapter_available (visual->adapter); GST_DEBUG_OBJECT (visual, "avail now %u", avail); /* we need at least 512 samples */ if (avail < 512 * visual->bps) break; /* we need at least enough samples to make one frame */ if (avail < visual->spf * visual->bps) break; /* get timestamp of the current adapter byte */ timestamp = gst_adapter_prev_timestamp (visual->adapter, &dist); if (GST_CLOCK_TIME_IS_VALID (timestamp)) { /* convert bytes to time */ dist /= visual->bps; timestamp += gst_util_uint64_scale_int (dist, GST_SECOND, visual->rate); } if (timestamp != -1) { gint64 qostime; /* QoS is done on running time */ qostime = gst_segment_to_running_time (&visual->segment, GST_FORMAT_TIME, timestamp); GST_OBJECT_LOCK (visual); /* check for QoS, don't compute buffers that are known to be late */ need_skip = visual->earliest_time != -1 && qostime <= visual->earliest_time; GST_OBJECT_UNLOCK (visual); if (need_skip) { GST_WARNING_OBJECT (visual, "QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (visual->earliest_time)); goto skip; } } /* Read 512 samples per channel */ data = (const guint16 *) gst_adapter_peek (visual->adapter, 512 * visual->bps); #if defined(VISUAL_API_VERSION) && VISUAL_API_VERSION >= 4000 && VISUAL_API_VERSION < 5000 { VisBuffer *lbuf, *rbuf; guint16 ldata[512], rdata[512]; VisAudioSampleRateType rate; lbuf = visual_buffer_new_with_buffer (ldata, sizeof (ldata), NULL); rbuf = visual_buffer_new_with_buffer (rdata, sizeof (rdata), NULL); if (visual->channels == 2) { for (i = 0; i < 512; i++) { ldata[i] = *data++; rdata[i] = *data++; } } else { for (i = 0; i < 512; i++) { ldata[i] = *data; rdata[i] = *data++; } } switch (visual->rate) { case 8000: rate = VISUAL_AUDIO_SAMPLE_RATE_8000; break; case 11250: rate = VISUAL_AUDIO_SAMPLE_RATE_11250; break; case 22500: rate = VISUAL_AUDIO_SAMPLE_RATE_22500; break; case 32000: rate = VISUAL_AUDIO_SAMPLE_RATE_32000; break; case 44100: rate = VISUAL_AUDIO_SAMPLE_RATE_44100; break; case 48000: rate = VISUAL_AUDIO_SAMPLE_RATE_48000; break; case 96000: rate = VISUAL_AUDIO_SAMPLE_RATE_96000; break; default: visual_object_unref (VISUAL_OBJECT (lbuf)); visual_object_unref (VISUAL_OBJECT (rbuf)); GST_ERROR_OBJECT (visual, "unsupported rate %d", visual->rate); ret = GST_FLOW_ERROR; goto beach; break; } visual_audio_samplepool_input_channel (visual->audio->samplepool, lbuf, rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16, (char *) VISUAL_AUDIO_CHANNEL_LEFT); visual_audio_samplepool_input_channel (visual->audio->samplepool, rbuf, rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16, (char *) VISUAL_AUDIO_CHANNEL_RIGHT); visual_object_unref (VISUAL_OBJECT (lbuf)); visual_object_unref (VISUAL_OBJECT (rbuf)); } #else if (visual->channels == 2) { for (i = 0; i < 512; i++) { visual->audio->plugpcm[0][i] = *data++; visual->audio->plugpcm[1][i] = *data++; } } else { for (i = 0; i < 512; i++) { visual->audio->plugpcm[0][i] = *data; visual->audio->plugpcm[1][i] = *data++; } } #endif /* alloc a buffer if we don't have one yet, this happens * when we pushed a buffer in this while loop before */ if (outbuf == NULL) { ret = get_buffer (visual, &outbuf); if (ret != GST_FLOW_OK) { goto beach; } } visual_video_set_buffer (visual->video, GST_BUFFER_DATA (outbuf)); visual_audio_analyze (visual->audio); visual_actor_run (visual->actor, visual->audio); visual_video_set_buffer (visual->video, NULL); GST_DEBUG_OBJECT (visual, "rendered one frame"); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = visual->duration; ret = gst_pad_push (visual->srcpad, outbuf); outbuf = NULL; skip: GST_DEBUG_OBJECT (visual, "finished frame, flushing %u samples from input", visual->spf); /* Flush out the number of samples per frame */ gst_adapter_flush (visual->adapter, visual->spf * visual->bps); /* quit the loop if something was wrong */ if (ret != GST_FLOW_OK) break; } beach: if (outbuf != NULL) gst_buffer_unref (outbuf); gst_object_unref (visual); return ret; }
static gboolean gst_visual_render (GstAudioVisualizer * bscope, GstBuffer * audio, GstVideoFrame * video) { GstVisual *visual = GST_VISUAL (bscope); GstMapInfo amap; const guint16 *adata; gint i, channels; gboolean res = TRUE; VisBuffer *lbuf, *rbuf; guint16 ldata[VISUAL_SAMPLES], rdata[VISUAL_SAMPLES]; VisAudioSampleRateType vrate; visual_video_set_buffer (visual->video, GST_VIDEO_FRAME_PLANE_DATA (video, 0)); visual_video_set_pitch (visual->video, GST_VIDEO_FRAME_PLANE_STRIDE (video, 0)); channels = GST_AUDIO_INFO_CHANNELS (&bscope->ainfo); gst_buffer_map (audio, &amap, GST_MAP_READ); adata = (const guint16 *) amap.data; lbuf = visual_buffer_new_with_buffer (ldata, sizeof (ldata), NULL); rbuf = visual_buffer_new_with_buffer (rdata, sizeof (rdata), NULL); if (channels == 2) { for (i = 0; i < VISUAL_SAMPLES; i++) { ldata[i] = *adata++; rdata[i] = *adata++; } } else { for (i = 0; i < VISUAL_SAMPLES; i++) { ldata[i] = *adata; rdata[i] = *adata++; } } /* TODO(ensonic): move to setup */ switch (bscope->ainfo.rate) { case 8000: vrate = VISUAL_AUDIO_SAMPLE_RATE_8000; break; case 11250: vrate = VISUAL_AUDIO_SAMPLE_RATE_11250; break; case 22500: vrate = VISUAL_AUDIO_SAMPLE_RATE_22500; break; case 32000: vrate = VISUAL_AUDIO_SAMPLE_RATE_32000; break; case 44100: vrate = VISUAL_AUDIO_SAMPLE_RATE_44100; break; case 48000: vrate = VISUAL_AUDIO_SAMPLE_RATE_48000; break; case 96000: vrate = VISUAL_AUDIO_SAMPLE_RATE_96000; break; default: visual_object_unref (VISUAL_OBJECT (lbuf)); visual_object_unref (VISUAL_OBJECT (rbuf)); GST_ERROR_OBJECT (visual, "unsupported rate %d", bscope->ainfo.rate); res = FALSE; goto done; } visual_audio_samplepool_input_channel (visual->audio->samplepool, lbuf, vrate, VISUAL_AUDIO_SAMPLE_FORMAT_S16, (char *) VISUAL_AUDIO_CHANNEL_LEFT); visual_audio_samplepool_input_channel (visual->audio->samplepool, rbuf, vrate, VISUAL_AUDIO_SAMPLE_FORMAT_S16, (char *) VISUAL_AUDIO_CHANNEL_RIGHT); visual_object_unref (VISUAL_OBJECT (lbuf)); visual_object_unref (VISUAL_OBJECT (rbuf)); visual_audio_analyze (visual->audio); visual_actor_run (visual->actor, visual->audio); visual_video_set_buffer (visual->video, NULL); GST_DEBUG_OBJECT (visual, "rendered one frame"); done: gst_buffer_unmap (audio, &amap); return res; }
/* Main stuff */ int main (int argc, char *argv[]) { int width = 1000, height = 600; int i, j; int freeze = 0; int depthflag = 0; int alpha = 128; bpp = 4; sdl_init (width, height); scrbuf = malloc (screen->pitch * screen->h); memset (scrbuf, 0, screen->pitch * screen->h); SDL_Event event; visual_init (&argc, &argv); if (argc > 1) actor = visual_actor_new (argv[1]); else actor = visual_actor_new ("G-Force"); visual_actor_realize (actor); video = visual_video_new (); visual_actor_set_video (actor, video); visual_video_set_depth (video, VISUAL_VIDEO_DEPTH_32BIT); visual_video_set_dimension (video, 256, 256); visual_video_allocate_buffer (video); visual_actor_video_negotiate (actor, 0, FALSE, FALSE); scalevid = visual_video_new (); visual_video_set_depth (scalevid, VISUAL_VIDEO_DEPTH_32BIT); visual_video_set_dimension (scalevid, 300, 400); visual_video_allocate_buffer (scalevid); sdlvid = visual_video_new (); visual_video_set_depth (sdlvid, VISUAL_VIDEO_DEPTH_32BIT); visual_video_set_dimension (sdlvid, screen->w, screen->h); visual_video_set_pitch (sdlvid, screen->pitch); visual_video_set_buffer (sdlvid, scrbuf); input = visual_input_new ("alsa"); visual_input_realize (input); while (1) { visual_input_run (input); visual_actor_run (actor, input->audio); /* place on screen */ visual_video_blit_overlay (sdlvid, video, 0, 0, FALSE); visual_video_set_palette (scalevid, visual_actor_get_palette (actor)); visual_video_scale (scalevid, video, VISUAL_VIDEO_SCALE_BILINEAR); visual_video_blit_overlay (sdlvid, scalevid, 256, 0, FALSE); sdl_draw_buf (); usleep (5000); while (SDL_PollEvent (&event)) { switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_F11: sdl_fullscreen_toggle (); break; case SDLK_q: alpha -= 8; if (alpha < 0) alpha = 0; break; case SDLK_a: alpha += 8; if (alpha > 255) alpha = 255; break; case SDLK_ESCAPE: goto out; break; } break; case SDL_VIDEORESIZE: sdl_size_request (event.resize.w, event.resize.h); break; case SDL_QUIT: goto out; break; } } } out: SDL_Quit (); }