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