diff --git a/ports/video-player/video-player.patch b/ports/video-player/video-player.patch index daf58eb6..c2537834 100644 --- a/ports/video-player/video-player.patch +++ b/ports/video-player/video-player.patch @@ -1,7 +1,7 @@ diff -Paur --no-dereference -- video-player.upstream/Makefile video-player/Makefile --- video-player.upstream/Makefile +++ video-player/Makefile -@@ -0,0 +1,36 @@ +@@ -0,0 +1,29 @@ +include ../../../build-aux/compiler.mak +include ../../../build-aux/version.mak +include ../../../build-aux/dirs.mak @@ -9,28 +9,21 @@ diff -Paur --no-dereference -- video-player.upstream/Makefile video-player/Makef +PKG_CONFIG?=pkg-config + +OPTLEVEL?=-g -O2 -+CXXFLAGS?=$(OPTLEVEL) ++CFLAGS?=$(OPTLEVEL) + +CPPFLAGS:=$(CPPFLAGS) -+CXXFLAGS:=$(CXXFLAGS) -Wall -Wextra -fno-exceptions -fno-rtti ++CFLAGS:=$(CFLAGS) -Wall -Wextra + +BINARY:=video-player +LIBS!=$(PKG_CONFIG) --libs libavcodec libavformat libswscale -+ -+DISPLAY:=$(shell $(LD) -ldisplay -o /dev/null 2>/dev/null && echo 1) -+ifeq ($(DISPLAY),1) +LIBS:=$(LIBS) -ldisplay -+CPPFLAGS:=$(CPPFLAGS) -DDISPLAY -+else -+LIBS:=$(LIBS) -ldispd -+endif + +all: $(BINARY) + +.PHONY: all install clean + -+%: %.cpp -+ $(CXX) -std=gnu++11 $(CXXFLAGS) $(CPPFLAGS) $< -o $@ $(LIBS) ++%: %.c ++ $(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $< -o $@ $(LIBS) + +install: all + mkdir -p $(DESTDIR)$(BINDIR) @@ -38,16 +31,32 @@ diff -Paur --no-dereference -- video-player.upstream/Makefile video-player/Makef + +clean: + rm -f $(BINARY) -diff -Paur --no-dereference -- video-player.upstream/video-player.cpp video-player/video-player.cpp ---- video-player.upstream/video-player.cpp -+++ video-player/video-player.cpp -@@ -0,0 +1,302 @@ -+#define __STDC_CONSTANT_MACROS -+#define __STDC_LIMIT_MACROS +diff -Paur --no-dereference -- video-player.upstream/video-player.c video-player/video-player.c +--- video-player.upstream/video-player.c ++++ video-player/video-player.c +@@ -0,0 +1,317 @@ ++/* ++ * Copyright (c) 2016, 2021, 2022, 2024 Jonas 'Sortie' Termansen. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * video-player.c ++ * Play videos. ++ */ + +#include ++#include +#include -+#include +#include +#include +#include @@ -55,110 +64,111 @@ diff -Paur --no-dereference -- video-player.upstream/video-player.cpp video-play +#include +#include + -+#ifdef DISPLAY +#include -+#else -+#include -+#endif + -+extern "C" { +#include +#include +#include -+} // extern "C" + -+uint32_t WINDOW_ID = 0; -+uint32_t WINDOW_WIDTH = 0; -+uint32_t WINDOW_HEIGHT = 0; ++static uint32_t WINDOW_ID = 0; ++static uint32_t WINDOW_WIDTH = 0; ++static uint32_t WINDOW_HEIGHT = 0; + -+bool need_show = true; -+bool need_exit = false; ++static int force_width = 0; ++static int force_height = 0; ++static int zoom = 100; + -+uint32_t* framebuffer = NULL; -+size_t framebuffer_size = 0; ++static bool need_show = true; ++static bool need_exit = false; + -+void on_disconnect(void*) ++static uint32_t* framebuffer = NULL; ++static size_t framebuffer_size = 0; ++ ++static void on_disconnect(void* ctx) +{ + need_exit = true; +} + -+void on_quit(void*, uint32_t window_id) ++static void on_quit(void* ctx, uint32_t window_id) +{ + if ( window_id != WINDOW_ID ) + return; + need_exit = true; +} + -+void on_resize(void*, uint32_t window_id, uint32_t width, uint32_t height) ++static void on_resize(void* ctx, uint32_t window_id, uint32_t width, ++ uint32_t height) +{ + if ( window_id != WINDOW_ID ) + return; + WINDOW_WIDTH = width; + WINDOW_HEIGHT = height; ++ force_width = width; ++ force_height = height; ++ zoom = 100; +} + -+void on_keyboard(void*, uint32_t window_id, uint32_t) ++static void on_keyboard(void* ctx, uint32_t window_id, uint32_t codepoint) +{ + if ( window_id != WINDOW_ID ) + return; +} + -+#ifdef DISPLAY -+static void DisplayVideoFrame(AVFrame* frame, struct display_connection* connection) -+#else -+static void DisplayVideoFrame(AVFrame* frame, struct dispd_window* window) -+#endif ++static void display_video_frame(AVFrame* frame, ++ struct display_connection* connection) +{ -+#ifdef DISPLAY ++ if ( need_show ) ++ { ++ WINDOW_WIDTH = ++ force_width ? force_width : (frame->width * zoom) / 100; ++ WINDOW_HEIGHT = ++ force_height ? force_height : (frame->height * zoom) / 100; ++ display_resize_window(connection, WINDOW_ID, WINDOW_WIDTH, ++ WINDOW_HEIGHT); ++ } ++ ++ if ( !WINDOW_WIDTH || !WINDOW_HEIGHT ) ++ return; ++ + size_t framebuffer_needed = sizeof(uint32_t) * WINDOW_WIDTH * WINDOW_HEIGHT; + if ( framebuffer_size != framebuffer_needed ) + { -+ framebuffer = (uint32_t*) realloc(framebuffer, framebuffer_size = framebuffer_needed); ++ framebuffer = ++ (uint32_t*) realloc(framebuffer, ++ framebuffer_size = framebuffer_needed); + memset(framebuffer, 255, framebuffer_needed); + } + uint32_t width = WINDOW_WIDTH; + uint32_t height = WINDOW_HEIGHT; -+#else -+ struct dispd_framebuffer* window_fb = dispd_begin_render(window); -+ uint32_t width = dispd_get_framebuffer_width(window_fb); -+ uint32_t height = dispd_get_framebuffer_height(window_fb); -+ uint32_t* framebuffer = (uint32_t*) dispd_get_framebuffer_data(window_fb); -+#endif + -+ SwsContext* sws_ctx = sws_getContext(frame->width, frame->height, -+ (AVPixelFormat) frame->format, width, -+ height, AV_PIX_FMT_RGB32, SWS_BILINEAR, -+ NULL, NULL, NULL); ++ struct SwsContext* sws_ctx = ++ sws_getContext(frame->width, frame->height, ++ (enum AVPixelFormat) frame->format, width, height, ++ AV_PIX_FMT_RGB32, SWS_BILINEAR, NULL, NULL, NULL); + assert(sws_ctx); + + uint8_t* data_arr[1] = { (uint8_t*) framebuffer }; + int stride_arr[1] = { (int) (sizeof(framebuffer[0]) * width) }; -+ sws_scale(sws_ctx, frame->data, frame->linesize, 0, frame->height, data_arr, -+ stride_arr); ++ ++ sws_scale(sws_ctx, (const uint8_t * const*) frame->data, frame->linesize, 0, ++ frame->height, data_arr, stride_arr); + + sws_freeContext(sws_ctx); + -+#ifdef DISPLAY -+ display_render_window(connection, WINDOW_ID, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, framebuffer); ++ display_render_window(connection, WINDOW_ID, 0, 0, WINDOW_WIDTH, ++ WINDOW_HEIGHT, framebuffer); + -+ struct display_event_handlers handlers; -+ memset(&handlers, 0, sizeof(handlers)); -+ handlers.disconnect_handler = on_disconnect; -+ handlers.quit_handler = on_quit; -+ handlers.resize_handler = on_resize; -+ handlers.keyboard_handler = on_keyboard; -+ while ( display_poll_event(connection, &handlers) == 0 ); -+#else -+ dispd_finish_render(window_fb); -+#endif ++ if ( need_show ) ++ { ++ display_show_window(connection, WINDOW_ID); ++ need_show = false; ++ } +} + -+#ifdef DISPLAY -+bool PlayVideo(const char* path, struct display_connection* connection) -+#else -+bool PlayVideo(const char* path, struct dispd_window* connection) -+#endif ++bool play_video(const char* path, struct display_connection* connection) +{ ++ need_show = true; ++ + bool ret = false; + int av_error; + AVFormatContext* format_ctx = NULL; @@ -176,13 +186,13 @@ diff -Paur --no-dereference -- video-player.upstream/video-player.cpp video-play + + if ( (av_error = avformat_open_input(&format_ctx, path, NULL, NULL)) < 0 ) + { -+ error(0, 0, "%s: cannot open: %i\n", path, av_error); ++ warnx("%s: cannot open: %i\n", path, av_error); + goto cleanup_done; + } + + if ( (av_error = avformat_find_stream_info(format_ctx, NULL)) < 0 ) + { -+ error(0, 0, "%s: avformat_find_stream_info: %i\n", path, av_error); ++ warnx("%s: avformat_find_stream_info: %i\n", path, av_error); + goto cleanup_input; + } + @@ -198,23 +208,28 @@ diff -Paur --no-dereference -- video-player.upstream/video-player.cpp video-play + + if ( !video_stream ) + { -+ error(0, 0, "%s: no video stream found\n", path); ++ warnx("%s: no video stream found\n", path); + goto cleanup_input; + } + -+ if ( video_codec && !(video_codec_ctx = avcodec_alloc_context3(video_codec))) ++ if ( video_codec && ++ !(video_codec_ctx = avcodec_alloc_context3(video_codec))) + goto cleanup_input; -+ if ( audio_codec && !(audio_codec_ctx = avcodec_alloc_context3(audio_codec))) ++ if ( audio_codec && ++ !(audio_codec_ctx = avcodec_alloc_context3(audio_codec))) + goto cleanup_video_codec_ctx; + -+ + if ( video_codec_ctx ) + { ++ video_codec_ctx->extradata = video_stream->codecpar->extradata; ++ video_codec_ctx->extradata_size = video_stream->codecpar->extradata_size; + if ( (av_error = avcodec_open2(video_codec_ctx, NULL, NULL)) < 0 ) + goto cleanup_audio_codec_ctx; + } + if ( audio_codec_ctx ) + { ++ audio_codec_ctx->extradata = audio_stream->codecpar->extradata; ++ audio_codec_ctx->extradata_size = audio_stream->codecpar->extradata_size; + if ( (av_error = avcodec_open2(audio_codec_ctx, NULL, NULL)) < 0 ) + goto cleanup_audio_codec_ctx; + } @@ -247,12 +262,21 @@ diff -Paur --no-dereference -- video-player.upstream/video-player.cpp video-play + clock_gettime(CLOCK_MONOTONIC, &now); + } + -+ DisplayVideoFrame(video_frame, connection); ++ display_video_frame(video_frame, connection); + + uintmax_t usecs = video_codec_ctx->ticks_per_frame * 1000000 * + video_codec_ctx->time_base.num / + video_codec_ctx->time_base.den; -+ next_frame_at = timespec_add(next_frame_at, timespec_make(0, usecs * 1000)); ++ next_frame_at = ++ timespec_add(next_frame_at, timespec_make(0, usecs * 1000)); ++ ++ struct display_event_handlers handlers; ++ memset(&handlers, 0, sizeof(handlers)); ++ handlers.disconnect_handler = on_disconnect; ++ handlers.quit_handler = on_quit; ++ handlers.resize_handler = on_resize; ++ handlers.keyboard_handler = on_keyboard; ++ while ( display_poll_event(connection, &handlers) == 0 ); + } + if ( av_error != AVERROR(EAGAIN) && av_error != AVERROR_EOF ) + goto break_decode_loop; @@ -280,12 +304,14 @@ diff -Paur --no-dereference -- video-player.upstream/video-player.cpp video-play +cleanup_audio_codec_ctx: + if ( audio_codec_ctx ) + { ++ audio_codec_ctx->extradata = NULL; + avcodec_close(audio_codec_ctx); + av_free(audio_codec_ctx); + } +cleanup_video_codec_ctx: + if ( video_codec_ctx ) + { ++ video_codec_ctx->extradata = NULL; + avcodec_close(video_codec_ctx); + av_free(video_codec_ctx); + } @@ -297,50 +323,32 @@ diff -Paur --no-dereference -- video-player.upstream/video-player.cpp video-play + +int main(int argc, char* argv[]) +{ -+#ifdef DISPLAY ++ int opt; ++ while ( (opt = getopt(argc, argv, "h:w:z:")) != -1 ) ++ { ++ switch ( opt ) ++ { ++ case 'h': force_height = atoi(optarg); break; ++ case 'w': force_width = atoi(optarg); break; ++ case 'z': zoom = atoi(optarg); break; ++ default: return 1; ++ } ++ } ++ + struct display_connection* connection = display_connect_default(); + if ( !connection ) -+ error(1, errno, "Could not connect to display server"); -+#else -+ if ( !isatty(0) ) -+ error(1, errno, "standard input"); -+ if ( !dispd_initialize(&argc, &argv) ) -+ error(1, 0, "couldn't initialize dispd library"); -+ struct dispd_session* session = dispd_attach_default_session(); -+ if ( !session ) -+ error(1, 0, "couldn't attach to dispd default session"); -+ if ( !dispd_session_setup_game_rgba(session) ) -+ error(1, 0, "couldn't setup dispd rgba session"); -+ struct dispd_window* window = dispd_create_window_game_rgba(session); -+ if ( !window ) -+ error(1, 0, "couldn't create dispd rgba window"); -+ struct dispd_window* connection = window; -+#endif -+ -+#ifdef DISPLAY -+ WINDOW_WIDTH = 800; -+ WINDOW_HEIGHT = 450; ++ err(1, "Could not connect to display server"); + + display_create_window(connection, WINDOW_ID); -+ display_resize_window(connection, WINDOW_ID, WINDOW_WIDTH, WINDOW_HEIGHT); -+ display_show_window(connection, WINDOW_ID); -+#endif + -+ for ( int i = 1; i < argc; i++ ) ++ for ( int i = optind; i < argc; i++ ) + { -+#ifdef DISPLAY + display_title_window(connection, WINDOW_ID, argv[i]); -+#endif -+ if ( !PlayVideo(argv[i], connection) ) ++ if ( !play_video(argv[i], connection) ) + return 1; + } + -+#ifdef DISPLAY + display_disconnect(connection); -+#else -+ dispd_destroy_window(window); -+ dispd_detach_session(session); -+#endif + + return 0; +} diff --git a/ports/video-player/video-player.port b/ports/video-player/video-player.port index 485ac491..2d215675 100644 --- a/ports/video-player/video-player.port +++ b/ports/video-player/video-player.port @@ -1,3 +1,4 @@ NAME=video-player BUILD_LIBRARIES=libavcodec BUILD_SYSTEM=sortix-usual-makefile +LICENSE=ISC