diff --git a/CMakeLists.txt b/CMakeLists.txt index 7be458688..c24a9a87b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,46 +9,66 @@ set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_VISIBILITY_PRESET hidden) -configure_file(tools/version.h.in include/version.h) - include(GNUInstallDirs) +option(DISABLE_FFMPEG "Disable FFmpeg image/video support" OFF) + +configure_file(tools/version.h.in include/version.h) + find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) pkg_check_modules(TERMINFO REQUIRED tinfo>=6.1) +if(NOT "${DISABLE_FFMPEG}") pkg_check_modules(AVUTIL REQUIRED libavutil>=56.0) pkg_check_modules(AVFORMAT REQUIRED libavformat>=57.0) pkg_check_modules(SWSCALE REQUIRED libswscale>=5.0) +endif() find_library(LIBRT rt) file(GLOB LIBSRCS CONFIGURE_DEPENDS src/lib/*.c) add_library(notcurses SHARED ${LIBSRCS}) -target_include_directories(notcurses - PRIVATE - include - "${PROJECT_BINARY_DIR}/include" - "${TERMINFO_INCLUDE_DIR}" - "${AVFORMAT_INCLUDE_DIR}" - "${SWSCALE_INCLUDE_DIR}" -) -target_link_libraries(notcurses - PRIVATE - "${TERMINFO_LIBRARIES}" - "${AVFORMAT_LIBRARIES}" - "${SWSCALE_LIBRARIES}" - "${LIBRT}" -) -target_link_directories(notcurses - PRIVATE - "${TERMINFO_LIBRARY_DIRS}" - "${AVFORMAT_LIBRARY_DIRS}" - "${SWSCALE_LIBRARY_DIRS}" -) set_target_properties(notcurses PROPERTIES PUBLIC_HEADER "include/notcurses.h" VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) +target_include_directories(notcurses + PRIVATE + include + "${PROJECT_BINARY_DIR}/include" + "${TERMINFO_INCLUDE_DIR}" +) +target_link_libraries(notcurses + PRIVATE + "${TERMINFO_LIBRARIES}" + "${LIBRT}" +) +target_link_directories(notcurses + PRIVATE + "${TERMINFO_LIBRARY_DIRS}" +) + +if(NOT "${DISABLE_FFMPEG}") +target_include_directories(notcurses + PRIVATE + "${AVFORMAT_INCLUDE_DIR}" + "${SWSCALE_INCLUDE_DIR}" +) +endif() +if(NOT "${DISABLE_FFMPEG}") +target_link_libraries(notcurses + PRIVATE + "${AVFORMAT_LIBRARIES}" + "${SWSCALE_LIBRARIES}" +) +endif() +if(NOT "${DISABLE_FFMPEG}") +target_link_directories(notcurses + PRIVATE + "${AVFORMAT_LIBRARY_DIRS}" + "${SWSCALE_LIBRARY_DIRS}" +) +endif() target_compile_options(notcurses PRIVATE @@ -135,7 +155,9 @@ target_compile_definitions(notcurses-planereel ) file(GLOB VIEWSRCS CONFIGURE_DEPENDS src/view/*.cpp) +if(NOT "${DISABLE_FFMPEG}") add_executable(notcurses-view ${VIEWSRCS}) +endif() target_include_directories(notcurses-view PRIVATE include @@ -151,6 +173,8 @@ target_link_libraries(notcurses-view notcurses PRIVATE "${AVUTIL_LIBRARIES}" + "${AVFORMAT_LIBRARIES}" + "${SWSCALE_LIBRARIES}" ) target_compile_options(notcurses-view PRIVATE @@ -167,6 +191,7 @@ find_package(GTest 1.9 REQUIRED) target_include_directories(notcurses-tester PRIVATE include + "${PROJECT_BINARY_DIR}/include" src/lib ) target_link_libraries(notcurses-tester @@ -230,7 +255,9 @@ install(FILES ) install(TARGETS notcurses-demo DESTINATION bin) +if(NOT "${DISABLE_FFMPEG}") install(TARGETS notcurses-view DESTINATION bin) +endif() install(TARGETS notcurses-input DESTINATION bin) install(TARGETS notcurses-planereel DESTINATION bin) install(TARGETS notcurses diff --git a/include/notcurses.h b/include/notcurses.h index d1ca4f411..dbba72925 100644 --- a/include/notcurses.h +++ b/include/notcurses.h @@ -15,9 +15,6 @@ #ifdef __cplusplus extern "C" { #define RESTRICT -#include -#include -#include // ffmpeg doesn't reliably "C"-guard itself #else #define RESTRICT restrict #endif diff --git a/src/lib/internal.h b/src/lib/internal.h index f90e4bcef..6f13d50cc 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -10,8 +10,18 @@ #include #include #include "notcurses.h" +#include "version.h" #include "egcpool.h" +#ifndef DISABLE_FFMPEG +#include +#include +#include +#include +#include +#include +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/src/lib/libav.c b/src/lib/libav.c index 823b1fea9..84200fc17 100644 --- a/src/lib/libav.c +++ b/src/lib/libav.c @@ -9,18 +9,9 @@ ncplane* ncvisual_plane(ncvisual* ncv){ return ncv->ncp; } -static ncvisual* -ncvisual_create(void){ - ncvisual* ret = malloc(sizeof(*ret)); - if(ret == NULL){ - return NULL; - } - memset(ret, 0, sizeof(*ret)); - return ret; -} - void ncvisual_destroy(ncvisual* ncv){ if(ncv){ +#ifndef DISABLE_FFMPEG avcodec_close(ncv->codecctx); avcodec_free_context(&ncv->codecctx); av_frame_free(&ncv->frame); @@ -30,6 +21,7 @@ void ncvisual_destroy(ncvisual* ncv){ av_packet_free(&ncv->packet); av_packet_free(&ncv->subtitle); avformat_close_input(&ncv->fmtctx); +#endif if(ncv->ncobj && ncv->ncp){ ncplane_destroy(ncv->ncp); } @@ -37,6 +29,17 @@ void ncvisual_destroy(ncvisual* ncv){ } } +#ifndef DISABLE_FFMPEG +static ncvisual* +ncvisual_create(void){ + ncvisual* ret = malloc(sizeof(*ret)); + if(ret == NULL){ + return NULL; + } + memset(ret, 0, sizeof(*ret)); + return ret; +} + /* static void print_frame_summary(const AVCodecContext* cctx, const AVFrame* f){ char pfmt[128]; @@ -75,7 +78,7 @@ print_frame_summary(const AVCodecContext* cctx, const AVFrame* f){ f->quality); }*/ -AVFrame* ncvisual_decode(struct ncvisual* nc, int* averr){ +AVFrame* ncvisual_decode(ncvisual* nc, int* averr){ bool have_frame = false; bool unref = false; do{ @@ -392,3 +395,51 @@ int ncvisual_init(void){ // FIXME could also use av_log_set_callback() and capture the message... return 0; } +#else +// built without ffmpeg + +AVFrame* ncvisual_decode(ncvisual* nc, int* averr){ + (void)nc; + (void)averr; + return NULL; +} + +int ncvisual_render(const ncvisual* ncv, int begy, int begx, int leny, int lenx){ + (void)ncv; + (void)begy; + (void)begx; + (void)leny; + (void)lenx; + return -1; +} + +int ncvisual_stream(notcurses* nc, ncvisual* ncv, int* averr, streamcb streamer){ + (void)nc; + (void)ncv; + (void)averr; + (void)streamer; + return -1; +} + +ncvisual* ncplane_visual_open(ncplane* nc, const char* filename, int* averr){ + (void)nc; + (void)filename; + (void)averr; + return NULL; +} + +ncvisual* ncvisual_open_plane(notcurses* nc, const char* filename, + int* averr, int y, int x, ncscale_e style){ + (void)nc; + (void)filename; + (void)averr; + (void)y; + (void)x; + (void)style; + return NULL; +} + +int ncvisual_init(void){ + return 0; +} +#endif diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index b81ed84e4..2221143b9 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,12 +13,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include "notcurses.h" #include "internal.h" #include "version.h" @@ -769,20 +764,22 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){ char prefixbuf[BPREFIXSTRLEN + 1]; fprintf(ret->ttyfp, "\n" " notcurses %s by nick black\n" + " %d rows, %d columns (%sB), %d colors (%s)\n" " compiled with gcc-%s\n" - " terminfo from %s\n" - " avformat %u.%u.%u\n" - " avutil %u.%u.%u\n" - " swscale %u.%u.%u\n" - " %d rows, %d columns (%sB), %d colors (%s)\n", - notcurses_version(), __VERSION__, - curses_version(), LIBAVFORMAT_VERSION_MAJOR, - LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO, - LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, - LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO, + " terminfo from %s\n", + notcurses_version(), ret->stdscr->leny, ret->stdscr->lenx, bprefix(ret->stats.fbbytes, 1, prefixbuf, 0), - ret->colors, ret->RGBflag ? "direct" : "palette"); + ret->colors, ret->RGBflag ? "direct" : "palette", + __VERSION__, curses_version()); +#ifndef DISABLE_FFMPEG + fprintf(ret->ttyfp, " avformat %u.%u.%u\navutil %u.%u.%u\nswscale %u.%u.%u\n", + LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO, + LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, + LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO); +#else + fprintf(ret->ttyfp, " warning: built without ffmpeg support\n"); +#endif if(!ret->RGBflag){ // FIXME if(ret->colors >= 16){ putp(tiparm(ret->setaf, 207)); diff --git a/src/view/view.cpp b/src/view/view.cpp index 6e02dc890..8dfd45954 100644 --- a/src/view/view.cpp +++ b/src/view/view.cpp @@ -6,6 +6,12 @@ #include #include "notcurses.h" +extern "C" { +#include +#include +#include // ffmpeg doesn't reliably "C"-guard itself +} + static void usage(std::ostream& os, const char* name, int exitcode) __attribute__ ((noreturn)); diff --git a/tests/internal.cpp b/tests/internal.cpp index 3840b2f53..d05e7de7f 100644 --- a/tests/internal.cpp +++ b/tests/internal.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "internal.h" #include "main.h" class InternalsTest : public :: testing::Test { diff --git a/tests/libav.cpp b/tests/libav.cpp index eee105437..6e61506a0 100644 --- a/tests/libav.cpp +++ b/tests/libav.cpp @@ -1,6 +1,11 @@ #include +#include "version.h" #include "main.h" +#ifndef DISABLE_FFMPEG +#include +#include +#include // ffmpeg doesn't reliably "C"-guard itself class LibavTest : public :: testing::Test { protected: void SetUp() override { @@ -87,3 +92,4 @@ TEST_F(LibavTest, LoadVideoCreatePlane) { EXPECT_EQ(0, notcurses_render(nc_)); ncvisual_destroy(ncv); } +#endif diff --git a/tests/main.h b/tests/main.h index e53e16cb1..80e941983 100644 --- a/tests/main.h +++ b/tests/main.h @@ -4,7 +4,6 @@ #include #include #include -#include "internal.h" // GTEST_SKIP only came along in GoogleTest 1.9 #ifndef GTEST_SKIP diff --git a/tests/ncplane.cpp b/tests/ncplane.cpp index bb370c578..847e6451e 100644 --- a/tests/ncplane.cpp +++ b/tests/ncplane.cpp @@ -1,5 +1,6 @@ #include #include +#include "internal.h" #include "main.h" class NcplaneTest : public :: testing::Test { diff --git a/tools/version.h.in b/tools/version.h.in index 38b0018cd..ec64708cd 100644 --- a/tools/version.h.in +++ b/tools/version.h.in @@ -1,3 +1,4 @@ #define notcurses_VERSION_MAJOR "@notcurses_VERSION_MAJOR@" #define notcurses_VERSION_MINOR "@notcurses_VERSION_MINOR@" #define notcurses_VERSION_PATCH "@notcurses_VERSION_PATCH@" +#cmakedefine DISABLE_FFMPEG