From 337326d7921cb8570db469312cbf2dbfb04c9fe4 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 6 Jun 2021 00:40:23 +0200 Subject: [PATCH] Simple test vlc scene from libvlc's sample code. Doesn't display videos at the moment for some reason. Will figure it out later. --- app/impl_application.h | 3 +- app/main_scene.cpp | 2 + app/vlc_scene.cpp | 172 +++++++++++++++++++++++++++++ app/vlc_scene.h | 33 ++++++ custom_modules/sdl/application.cpp | 2 - main.cpp | 7 +- 6 files changed, 213 insertions(+), 6 deletions(-) create mode 100644 app/vlc_scene.cpp create mode 100644 app/vlc_scene.h diff --git a/app/impl_application.h b/app/impl_application.h index 0441467..48db7d6 100644 --- a/app/impl_application.h +++ b/app/impl_application.h @@ -4,11 +4,12 @@ #include "application.h" #include "main_scene.h" +#include "vlc_scene.h" class ImplApplication : public Application { public: ImplApplication() : Application() { - scene = new MainScene(); + scene = new VLCScene(); } ~ImplApplication() { delete scene; diff --git a/app/main_scene.cpp b/app/main_scene.cpp index de863fe..7283956 100644 --- a/app/main_scene.cpp +++ b/app/main_scene.cpp @@ -26,6 +26,8 @@ void MainScene::render() { b3->render(); _ts->draw(); + + Renderer::get_singleton()->present(); } MainScene::MainScene() { diff --git a/app/vlc_scene.cpp b/app/vlc_scene.cpp new file mode 100644 index 0000000..13deb87 --- /dev/null +++ b/app/vlc_scene.cpp @@ -0,0 +1,172 @@ +#include "vlc_scene.h" + +#include "renderer/renderer.h" + +#include + +#include +#include +#include +#include +#include + +#define VIDEOWIDTH 320 +#define VIDEOHEIGHT 240 + +// VLC prepares to render a video frame. +static void *lock(void *data, void **p_pixels) { + + VLCScene *c = (VLCScene *)data; + + int pitch; + SDL_LockMutex(c->mutex); + SDL_LockTexture(c->texture, NULL, p_pixels, &pitch); + + return NULL; // Picture identifier, not needed here. +} + +// VLC just rendered a video frame. +static void unlock(void *data, void *id, void *const *p_pixels) { + + VLCScene *c = (VLCScene *)data; + + uint16_t *pixels = (uint16_t *)*p_pixels; + + // We can also render stuff. + int x, y; + for (y = 10; y < 40; y++) { + for (x = 10; x < 40; x++) { + if (x < 13 || y < 13 || x > 36 || y > 36) { + pixels[y * VIDEOWIDTH + x] = 0xffff; + } else { + // RV16 = 5+6+5 pixels per color, BGR. + pixels[y * VIDEOWIDTH + x] = 0x02ff; + } + } + } + + SDL_UnlockTexture(c->texture); + SDL_UnlockMutex(c->mutex); +} + +// VLC wants to display a video frame. +static void display(void *data, void *id) { + + VLCScene *c = (VLCScene *)data; + + int w = Renderer::get_singleton()->get_window_size_w(); + int h = Renderer::get_singleton()->get_window_size_h(); + + SDL_Rect rect; + rect.w = VIDEOWIDTH; + rect.h = VIDEOHEIGHT; + rect.x = (int)((1. + .5 * sin(0.03 * c->n)) * (w - VIDEOWIDTH) / 2); + rect.y = (int)((1. + .5 * cos(0.03 * c->n)) * (h - VIDEOHEIGHT) / 2); + + Renderer::get_singleton()->set_draw_color(0, 80, 0, 255); + Renderer::get_singleton()->clear(); + SDL_RenderCopy(Renderer::get_singleton()->get_renderer(), c->texture, NULL, &rect); + //Renderer::get_singleton()->present(); + + //SDL_SetRenderDrawColor(Renderer::get_singleton()->get_renderer(), 0, 80, 0, 255); + //SDL_RenderClear(Renderer::get_singleton()->get_renderer()); + //SDL_RenderCopy(Renderer::get_singleton()->get_renderer(), c->texture, NULL, &rect); + //SDL_RenderPresent(Renderer::get_singleton()->get_renderer()); +} + +void VLCScene::event(const SDL_Event &ev) { + + action = 0; + + switch (ev.type) { + case SDL_KEYDOWN: + action = ev.key.keysym.sym; + break; + } + + switch (action) { + case ' ': + printf("Pause toggle.\n"); + pause = !pause; + break; + } +} + +void VLCScene::update(float delta) { + if (!r) { + r = true; + printf("play\n"); + libvlc_media_player_play(mp); + } + + if (!pause) { + n++; + } +} + +void VLCScene::render() { + Renderer::get_singleton()->present(); +} + +VLCScene::VLCScene() { + r = false; + done = 0; + action = 0; + pause = 0; + + texture = SDL_CreateTexture( + Renderer::get_singleton()->get_renderer(), + SDL_PIXELFORMAT_BGR565, SDL_TEXTUREACCESS_STREAMING, + VIDEOWIDTH, VIDEOHEIGHT); + + if (!texture) { + fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError()); + return; + } + + mutex = SDL_CreateMutex(); + + char const *vlc_argv[] = { + //"--no-audio", // Don't play audio. + "--no-xlib", // Don't use Xlib. + + // Apply a video filter. + //"--video-filter", "sepia", + //"--sepia-intensity=200" + }; + int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + + if (getenv("VLC_PLUGIN_PATH") == nullptr) { + setenv("VLC_PLUGIN_PATH", "/usr/lib/vlc/plugins", 1); + } + + // If you don't have this variable set you must have plugins directory + // with the executable or libvlc_new() will not work! + printf("VLC_PLUGIN_PATH=%s\n", getenv("VLC_PLUGIN_PATH")); + + // Initialise libVLC. + libvlc = libvlc_new(vlc_argc, vlc_argv); + if (NULL == libvlc) { + printf("LibVLC initialization failure.\n"); + return; + } + + m = libvlc_media_new_path(libvlc, "./test.mp4"); + + mp = libvlc_media_player_new_from_media(m); + libvlc_media_release(m); + + libvlc_video_set_callbacks(mp, lock, unlock, display, this); + libvlc_video_set_format(mp, "RV16", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH * 2); +} + +VLCScene::~VLCScene() { + + // Stop stream and clean up libVLC. + libvlc_media_player_stop(mp); + libvlc_media_player_release(mp); + libvlc_release(libvlc); + + // Close window and clean up libSDL. + SDL_DestroyMutex(mutex); +} diff --git a/app/vlc_scene.h b/app/vlc_scene.h new file mode 100644 index 0000000..ebaae10 --- /dev/null +++ b/app/vlc_scene.h @@ -0,0 +1,33 @@ +#ifndef VLC_SCENE_H +#define VLC_SCENE_H + +#include "scene.h" + +#include + +#include "vlc/vlc.h" + +class VLCScene : public Scene { +public: + void event(const SDL_Event &ev); + void update(float delta); + void render(); + + VLCScene(); + ~VLCScene(); + + SDL_Texture *texture; + SDL_mutex *mutex; + int n; + + libvlc_instance_t *libvlc; + libvlc_media_t *m; + libvlc_media_player_t *mp; + + bool r; + int done; + int action; + int pause; +}; + +#endif \ No newline at end of file diff --git a/custom_modules/sdl/application.cpp b/custom_modules/sdl/application.cpp index b5da868..65a5c2f 100644 --- a/custom_modules/sdl/application.cpp +++ b/custom_modules/sdl/application.cpp @@ -21,8 +21,6 @@ void Application::update(float delta) { } void Application::render() { scene->render(); - - Renderer::get_singleton()->present(); } void Application::main_loop() { diff --git a/main.cpp b/main.cpp index 90ccded..34dd338 100644 --- a/main.cpp +++ b/main.cpp @@ -96,6 +96,8 @@ int main(int argc, char **argv) { mqtt_server->add_local_session( "a/b", [](const std::string &client_id, const std::vector &data, void *obj) { reinterpret_cast(obj)->mqtt_sensor_callback(client_id, data); }, app); + TTF_Init(); + Renderer *renderer = new Renderer(); ImplApplication *sdl_app = new ImplApplication(); @@ -105,18 +107,17 @@ int main(int argc, char **argv) { //mqtt_server->run_async(); //server->main_loop(); - TTF_Init(); - while (sdl_app->running) { sdl_app->main_loop(); } - TTF_Quit(); } else { printf("Running migrations.\n"); app->migrate(); } + TTF_Quit(); + delete sdl_app; delete renderer;