bool Actor::video_negotiate (VisVideoDepth run_depth, bool noevent, bool forced) { auto output_width = m_impl->video->get_width (); auto output_height = m_impl->video->get_height (); auto output_depth = m_impl->video->get_depth (); // Ask actor for preferred rendering dimensions int run_width = output_width; int run_height = output_height; m_impl->get_actor_plugin ()->requisition (m_impl->plugin, &run_width, &run_height); // Check to make sure requested run depth is supported. If not, pick the highest. auto supported_depths = get_supported_depths (); m_impl->run_depth = forced ? run_depth : visual_video_depth_get_highest_nogl (supported_depths); if (!visual_video_depth_is_supported (supported_depths, m_impl->run_depth)) { m_impl->run_depth = visual_video_depth_get_highest_nogl (supported_depths); } // Configure proxy videos to convert rendering m_impl->to_scale.reset (); m_impl->to_convert.reset (); visual_log (VISUAL_LOG_DEBUG, "Setting up any necessary video conversions.."); if (output_depth != VISUAL_VIDEO_DEPTH_GL) { // Configure any necessary depth conversion if (m_impl->run_depth != output_depth) { visual_log (VISUAL_LOG_DEBUG, "Setting up depth conversion: %s -> %s", visual_video_depth_name (m_impl->run_depth), visual_video_depth_name (output_depth)); m_impl->to_convert = Video::create (output_width, output_height, m_impl->run_depth); } // Configure any necessary scaling if (run_width != output_width || run_height != output_height) { visual_log (VISUAL_LOG_DEBUG, "Setting up scaling: (%dx%d) -> (%dx%d)", run_width, run_height, output_width, output_height); m_impl->to_scale = Video::create (run_width, run_height, output_depth); } } else { visual_log (VISUAL_LOG_DEBUG, "Conversions skipped in OpenGL rendering mode"); } // FIXME: This should be moved into the if block above. It's out // here because plugins depend on this to receive information // about initial dimensions if (!noevent) { visual_event_queue_add (visual_plugin_get_event_queue (m_impl->plugin), visual_event_new_resize (run_width, run_height)); } return true; }
static void fix_depth_with_bin (VisBin *bin, VisVideo *video, int depth) { /* Is supported within bin natively */ if ((bin->depthflag & depth) > 0) { visual_video_set_depth (video, depth); } else { /* Not supported by the bin, taking the highest depth from the bin */ visual_video_set_depth (video, visual_video_depth_get_highest_nogl (bin->depthflag)); } }
static int negotiate_video_with_unsupported_depth (VisActor *actor, int rundepth, int noevent, int forced) { VisActorPlugin *actplugin = get_actor_plugin (actor); int depthflag = visual_actor_get_supported_depth (actor); /* Depth transform enviroment, it automaticly * fits size because it can use the pitch from * the dest video context */ actor->transform = visual_video_new (); visual_log (VISUAL_LOG_INFO, _("run depth %d forced %d\n"), rundepth, forced); if (forced == TRUE) visual_video_set_depth (actor->transform, rundepth); else visual_video_set_depth (actor->transform, visual_video_depth_get_highest_nogl (depthflag)); visual_log (VISUAL_LOG_INFO, _("transpitch1 %d depth %d bpp %d"), actor->transform->pitch, actor->transform->depth, actor->transform->bpp); /* If there is only GL (which gets returned by highest nogl if * nothing else is there, stop here */ if (actor->transform->depth == VISUAL_VIDEO_DEPTH_GL) return -VISUAL_ERROR_ACTOR_GL_NEGOTIATE; visual_video_set_dimension (actor->transform, actor->video->width, actor->video->height); visual_log (VISUAL_LOG_INFO, _("transpitch2 %d %d"), actor->transform->width, actor->transform->pitch); actplugin->requisition (visual_actor_get_plugin (actor), &actor->transform->width, &actor->transform->height); visual_log (VISUAL_LOG_INFO, _("transpitch3 %d"), actor->transform->pitch); if (noevent == FALSE) { visual_event_queue_add_resize (&actor->plugin->eventqueue, actor->transform, actor->transform->width, actor->transform->height); visual_plugin_events_pump (actor->plugin); } else { /* Normally a visual_video_set_dimension get's called within the * event handler, but we won't come there right now so we've * got to set the pitch ourself */ visual_video_set_dimension (actor->transform, actor->transform->width, actor->transform->height); } visual_log (VISUAL_LOG_INFO, _("rundepth: %d transpitch %d\n"), rundepth, actor->transform->pitch); visual_video_allocate_buffer (actor->transform); if (actor->video->depth == VISUAL_VIDEO_DEPTH_8BIT) actor->ditherpal = visual_palette_new (256); return VISUAL_OK; }
int visual_bin_connect_by_names (VisBin *bin, char *actname, char *inname) { VisActor *actor; VisInput *input; int depthflag; int depth; visual_log_return_val_if_fail (bin != NULL, -1); /* Create the actor */ actor = visual_actor_new (actname); visual_log_return_val_if_fail (actor != NULL, -1); /* Check and set required depth */ depthflag = visual_actor_get_supported_depth (actor); /* GL plugin, and ONLY a GL plugin */ if (depthflag == VISUAL_VIDEO_DEPTH_GL) visual_bin_set_depth (bin, VISUAL_VIDEO_DEPTH_GL); else { depth = bin_get_depth_using_preferred (bin, depthflag); /* Is supported within bin natively */ if ((bin->depthflag & depth) > 0) { visual_bin_set_depth (bin, depth); } else { /* Not supported by the bin, taking the highest depth from the bin */ visual_bin_set_depth (bin, visual_video_depth_get_highest_nogl (bin->depthflag)); } } /* Initialize the managed depth */ bin->depthforcedmain = bin->depth; /* Create the input */ input = visual_input_new (inname); visual_log_return_val_if_fail (input != NULL, -1); /* Connect */ visual_bin_connect (bin, actor, input); bin->managed = TRUE; bin->inputmanaged = TRUE; return 0; }
int main (int argc, char **argv) { // print warm welcome std::cerr << argv[0] << " v0.1\n"; // initialize libvisual once (this is meant to be called only once, // visual_init() after visual_quit() results in undefined state) visual_log_set_verbosity(VISUAL_LOG_DEBUG); visual_init (&argc, &argv); try { // parse commandline arguments if (_parse_args(argc, argv) != EXIT_SUCCESS) throw std::runtime_error ("Failed to parse arguments"); // create new VisBin for video output VisBin *bin = visual_bin_new(); visual_bin_set_supported_depth(bin, VISUAL_VIDEO_DEPTH_ALL); visual_bin_switch_set_style(bin, VISUAL_SWITCH_STYLE_MORPH); // initialize actor plugin std::cerr << "Loading actor '" << actor_name << "'...\n"; VisActor *actor = visual_actor_new (actor_name.c_str ()); if (!actor) throw std::runtime_error ("Failed to load actor '" + actor_name + "'"); // Set random seed if (have_seed) { VisPluginData *plugin_data = visual_actor_get_plugin(actor); VisRandomContext *r_context = visual_plugin_get_random_context (plugin_data); visual_random_context_set_seed (r_context, seed); seed++; } // initialize input plugin std::cerr << "Loading input '" << input_name << "'...\n"; VisInput *input = visual_input_new(input_name.c_str()); if (!input) { throw std::runtime_error ("Failed to load input '" + input_name + "'"); } // Pick the best display depth int depthflag = visual_actor_get_supported_depth (actor); VisVideoDepth depth; if (depthflag == VISUAL_VIDEO_DEPTH_GL) { depth = visual_video_depth_get_highest (depthflag); } else { depth = visual_video_depth_get_highest_nogl (depthflag); } visual_bin_set_depth (bin, depth); VisVideoAttributeOptions const* vidoptions = visual_actor_get_video_attribute_options(actor); // initialize display SADisplay display (driver_name); // create display display.create(depth, vidoptions, width, height, true); VisVideo *video = display.get_video(); if(!video) throw std::runtime_error("Failed to get VisVideo from display"); // put it all together visual_bin_connect(bin, actor, input); visual_bin_set_video(bin, video); visual_bin_realize(bin); visual_bin_sync(bin, FALSE); visual_bin_depth_changed(bin); // get a queue to handle events VisEventQueue localqueue; // main loop bool running = true; bool visible = true; while (running) { LV::Event ev; // Handle all events display.drain_events(localqueue); LV::EventQueue* pluginqueue = visual_plugin_get_eventqueue(visual_actor_get_plugin (bin->actor)); while (localqueue.poll(ev)) { if(ev.type != VISUAL_EVENT_RESIZE) pluginqueue->add (ev); switch (ev.type) { case VISUAL_EVENT_PARAM: { break; } case VISUAL_EVENT_RESIZE: { display.lock(); width = ev.event.resize.width; height = ev.event.resize.height; display.create(depth, vidoptions, width, height, true); video = display.get_video (); visual_bin_set_video (bin, video); visual_actor_video_negotiate (bin->actor, depth, FALSE, FALSE); display.unlock(); break; } case VISUAL_EVENT_MOUSEMOTION: { break; } case VISUAL_EVENT_MOUSEBUTTONDOWN: { // switch to next actor v_cycleActor(1); v_cycleMorph(); visual_bin_set_morph_by_name(bin, morph_name.c_str()); visual_bin_switch_actor_by_name(bin, actor_name.c_str()); // get new actor actor = visual_bin_get_actor(bin); // handle depth of new actor depthflag = visual_actor_get_supported_depth(actor); if (depthflag == VISUAL_VIDEO_DEPTH_GL) { visual_bin_set_depth(bin, VISUAL_VIDEO_DEPTH_GL); } else { depth = visual_video_depth_get_highest(depthflag); if ((bin->depthflag & depth) > 0) visual_bin_set_depth(bin, depth); else visual_bin_set_depth(bin, visual_video_depth_get_highest_nogl(bin->depthflag)); } bin->depthforcedmain = bin->depth; break; } case VISUAL_EVENT_MOUSEBUTTONUP: { break; } case VISUAL_EVENT_KEYDOWN: { switch(ev.event.keyboard.keysym.sym) { case VKEY_ESCAPE: { running = false; break; } case VKEY_TAB: { break; } default: break; } break; } case VISUAL_EVENT_KEYUP: { break; } case VISUAL_EVENT_QUIT: { running = FALSE; break; } case VISUAL_EVENT_VISIBILITY: { visible = ev.event.visibility.is_visible; break; } default: { break; } } } if (visual_bin_depth_changed(bin)) { display.lock(); display.create(depth, vidoptions, width, height, true); VisVideo *video = display.get_video(); visual_bin_set_video(bin, video); visual_bin_sync(bin, TRUE); display.unlock(); } // Do a run cycle if (!visible) continue; display.lock(); visual_bin_run(bin); display.unlock(); display.update_all(); display.set_fps_limit(framerate); } } catch (std::exception& error) { std::cerr << error.what () << std::endl; } //printf ("Total frames: %d, average fps: %f\n", display_fps_total (display), display_fps_average (display)); visual_quit (); return EXIT_SUCCESS; }
/** VisVideo.depthGetHighestNoGl() */ JNIEXPORT jint JNICALL Java_org_libvisual_android_VisVideo_videoGetHighestDepthNoGl(JNIEnv * env, jobject obj, jint depth) { LOGI("VisVideo.videoGetHighestDepthNoGl()"); return visual_video_depth_get_highest_nogl(depth); }
int main (int argc, char **argv) { try { // print warm welcome std::cerr << visual_truncate_path (argv[0], 1) << " - " << PACKAGE_STRING << " (" << LV_REVISION << ") commandline tool - " << PACKAGE_URL << "\n"; // setup signal handlers setup_signal_handlers (); // default loglevel visual_log_set_verbosity (VISUAL_LOG_ERROR); // initialize LV Libvisual main {argc, argv}; // parse commandline arguments int parse_result = parse_args (argc, argv); if (parse_result < 0) { throw std::runtime_error ("Failed to parse arguments"); } if (parse_result > 0) { return EXIT_SUCCESS; } // Set system-wide random seed if (have_seed) { LV::System::instance()->set_rng_seed (seed); } // create new VisBin for video output LV::Bin bin; bin.set_supported_depth(VISUAL_VIDEO_DEPTH_ALL); bin.use_morph(false); // Let the bin manage plugins. There's a bug otherwise. if (!bin.connect(actor_name, input_name)) { throw std::runtime_error ("Failed to start pipeline with actor '" + actor_name + "' and input '" + input_name + "'"); } auto actor = bin.get_actor(); // Select output colour depth VisVideoDepth depth; int depthflag = actor->get_supported_depths (); // Pick the best display depth directly supported by non GL actor if(depthflag != VISUAL_VIDEO_DEPTH_GL) { if (color_depth == 0) { depth = visual_video_depth_get_highest_nogl (depthflag); } // Pick user chosen colordepth else { depth = visual_video_depth_from_bpp (color_depth); } } /* GL actor */ else { depth = visual_video_depth_get_highest (depthflag); } bin.set_depth (depth); auto vidoptions = actor->get_video_attribute_options (); // initialize display Display display (driver_name); // create display auto video = display.create(depth, vidoptions, width, height, true); if(!video) { throw std::runtime_error("Failed to setup display for rendering"); } // Set the display title display.set_title(_("lv-tool")); // put it all together bin.set_video(video); bin.realize(); bin.sync(false); bin.depth_changed(); bin.set_morph(morph_name); // get a queue to handle events LV::EventQueue localqueue; // rendering statistics uint64_t frames_drawn = 0; // frame rate control state uint64_t const frame_period_us = frame_rate > 0 ? VISUAL_USECS_PER_SEC / frame_rate : 0; LV::Time last_frame_time; bool draw_frame = true; // main loop bool running = true; //bool visible = true; while (running) { // Check if process termination was signaled if (terminate_process) { std::cerr << "Received signal to terminate process, exiting..\n"; return EXIT_SUCCESS; } // Control frame rate if (frame_rate > 0) { if (frames_drawn > 0) { draw_frame = (LV::Time::now () - last_frame_time).to_usecs () >= frame_period_us; } } if (draw_frame) { DisplayLock lock {display}; // Draw audio data and render bin.run(); // Display rendering display.update_all (); // Record frame time last_frame_time = LV::Time::now (); // All frames rendered? frames_drawn++; if (frame_count > 0 && frames_drawn >= frame_count) { break; } // switch actor? if (actor_switch_after_frames > 0 && frames_drawn >= actor_switch_after_frames + actor_switch_framecount) { actor_switch_framecount += actor_switch_after_frames; actor_name = cycle_actor_name (actor_name, CycleDir::NEXT); std::cerr << "Switching to actor '" << actor_name << "'...\n"; bin.switch_actor (actor_name); } } LV::Event ev; // Handle all events display.drain_events(localqueue); auto pluginqueue = visual_plugin_get_event_queue (bin.get_actor()->get_plugin ()); while (localqueue.poll(ev)) { if(ev.type != VISUAL_EVENT_RESIZE) pluginqueue->add (ev); switch (ev.type) { case VISUAL_EVENT_PARAM: { break; } case VISUAL_EVENT_RESIZE: { DisplayLock lock {display}; width = ev.event.resize.width; height = ev.event.resize.height; video = display.create(depth, vidoptions, width, height, true); display.set_title(_("lv-tool")); bin.set_video (video); bin.sync(false); break; } case VISUAL_EVENT_MOUSEMOTION: { break; } case VISUAL_EVENT_MOUSEBUTTONDOWN: { // switch to next actor actor_name = cycle_actor_name (actor_name, CycleDir::NEXT); std::cerr << "Switching to actor '" << actor_name << "'...\n"; bin.switch_actor (actor_name); break; } case VISUAL_EVENT_MOUSEBUTTONUP: { break; } case VISUAL_EVENT_KEYDOWN: { switch(ev.event.keyboard.keysym.sym) { case VKEY_ESCAPE: { running = false; break; } case VKEY_TAB: { break; } default: break; } break; } case VISUAL_EVENT_KEYUP: { break; } case VISUAL_EVENT_QUIT: { running = false; break; } case VISUAL_EVENT_VISIBILITY: { //visible = ev.event.visibility.is_visible; break; } default: { break; } } } if (bin.depth_changed()) { DisplayLock lock {display}; int depthflag = bin.get_depth(); VisVideoDepth depth = visual_video_depth_get_highest(depthflag); display.create(depth, vidoptions, width, height, true); video = display.get_video(); bin.set_video(video); bin.sync(true); } } return EXIT_SUCCESS; } catch (std::exception& error) { std::cerr << error.what () << std::endl; return EXIT_FAILURE; } }