notcurses_canopen: split into images/videos #598

This commit is contained in:
nick black 2020-05-12 20:10:53 -04:00
parent 999c6c0742
commit 9a80750316
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
15 changed files with 93 additions and 58 deletions

View File

@ -10,6 +10,8 @@ rearrangements of Notcurses.
* `ncvisual_from_plane()`, `ncplane_move_below_unsafe()`, `ncplane_dup()`, * `ncvisual_from_plane()`, `ncplane_move_below_unsafe()`, `ncplane_dup()`,
and `ncplane_move_above_unsafe()` now accept `const` arguments where they and `ncplane_move_above_unsafe()` now accept `const` arguments where they
did not before. did not before.
* `notcurses_canopen()` has been split into `notcurses_canopen_images()` and
`notcurses_canopen_videos()`.
* 1.4.1 (2020-05-11) * 1.4.1 (2020-05-11)
* No user-visible changes (fixed two unit tests). * No user-visible changes (fixed two unit tests).

View File

@ -225,8 +225,11 @@ int notcurses_palette_size(const struct notcurses* nc);
// Can we fade? Fading requires either the "rgb" or "ccc" terminfo capability. // Can we fade? Fading requires either the "rgb" or "ccc" terminfo capability.
bool notcurses_canfade(const struct notcurses* nc); bool notcurses_canfade(const struct notcurses* nc);
// Can we load images/videos? This requires being built against FFmpeg. // Can we load images? This requires being built against FFmpeg/OIIO.
bool notcurses_canopen(const struct notcurses* nc); bool notcurses_canopen_images(const struct notcurses* nc);
// Can we load videos? This requires being built against FFmpeg.
bool notcurses_canopen_videos(const struct notcurses* nc);
// Can we change colors in the hardware palette? Requires "ccc" and "initc". // Can we change colors in the hardware palette? Requires "ccc" and "initc".
bool notcurses_canchangecolors(const struct notcurses* nc); bool notcurses_canchangecolors(const struct notcurses* nc);

View File

@ -101,9 +101,14 @@ namespace ncpp
return notcurses_canfade (nc); return notcurses_canfade (nc);
} }
bool can_open () const noexcept bool can_open_images () const noexcept
{ {
return notcurses_canopen (nc); return notcurses_canopen_images (nc);
}
bool can_open_videos () const noexcept
{
return notcurses_canopen_videos (nc);
} }
bool can_change_color () const noexcept bool can_change_color () const noexcept

View File

@ -1028,8 +1028,11 @@ API bool notcurses_canfade(const struct notcurses* nc);
// Can we set the "hardware" palette? Requires the "ccc" terminfo capability. // Can we set the "hardware" palette? Requires the "ccc" terminfo capability.
API bool notcurses_canchangecolor(const struct notcurses* nc); API bool notcurses_canchangecolor(const struct notcurses* nc);
// Can we load images/videos? This requires being built against FFmpeg. // Can we load images? This requires being built against FFmpeg/OIIO.
API bool notcurses_canopen(const struct notcurses* nc); API bool notcurses_canopen_images(const struct notcurses* nc);
// Can we load videos? This requires being built against FFmpeg.
API bool notcurses_canopen_videos(const struct notcurses* nc);
// Is our encoding UTF-8? // Is our encoding UTF-8?
API bool notcurses_canutf8(const struct notcurses* nc); API bool notcurses_canutf8(const struct notcurses* nc);

View File

@ -48,7 +48,7 @@ chunli_draw(struct notcurses* nc, const char* ext, int count, const cell* b){
// test of sprites from files // test of sprites from files
int chunli_demo(struct notcurses* nc){ int chunli_demo(struct notcurses* nc){
if(!notcurses_canopen(nc)){ if(!notcurses_canopen_images(nc)){
return 0; return 0;
} }
struct timespec iterdelay; struct timespec iterdelay;

View File

@ -199,7 +199,7 @@ eagles(struct notcurses* nc){
// motherfucking eagles! // motherfucking eagles!
int eagle_demo(struct notcurses* nc){ int eagle_demo(struct notcurses* nc){
if(!notcurses_canopen(nc)){ if(!notcurses_canopen_images(nc)){
return 0; return 0;
} }
char* map = find_data("eagles.png"); char* map = find_data("eagles.png");

View File

@ -143,7 +143,7 @@ draw_luigi(struct ncplane* n, const char* sprite){
} }
int luigi_demo(struct notcurses* nc){ int luigi_demo(struct notcurses* nc){
if(!notcurses_canopen(nc)){ if(!notcurses_canopen_images(nc)){
return 0; return 0;
} }
int rows, cols; int rows, cols;

View File

@ -120,7 +120,7 @@ outro_message(struct notcurses* nc, int* rows, int* cols){
} }
int outro(struct notcurses* nc){ int outro(struct notcurses* nc){
if(!notcurses_canopen(nc)){ if(!notcurses_canopen_images(nc)){
return 0; return 0;
} }
int rows, cols; int rows, cols;
@ -150,14 +150,16 @@ int outro(struct notcurses* nc){
y = ystart - 1; y = ystart - 1;
DEMO_RENDER(nc); DEMO_RENDER(nc);
ncplane_move_top(on); ncplane_move_top(on);
pthread_t tid; if(notcurses_canopen_videos(nc)){
// will fade across 2 * demodelay pthread_t tid;
targy = 3; // will fade across 2 * demodelay
pthread_create(&tid, NULL, fadethread, nc); targy = 3;
void* ret; pthread_create(&tid, NULL, fadethread, nc);
pthread_join(tid, &ret); void* ret;
if(ret == PTHREAD_CANCELED){ pthread_join(tid, &ret);
return 1; if(ret == PTHREAD_CANCELED){
return 1;
}
} }
ncplane_fadeout(on, &demodelay, demo_fader, NULL); ncplane_fadeout(on, &demodelay, demo_fader, NULL);
ncplane_destroy(on); ncplane_destroy(on);

View File

@ -65,7 +65,7 @@ legend(struct notcurses* nc, int dimy, int dimx){
} }
int view_demo(struct notcurses* nc){ int view_demo(struct notcurses* nc){
if(!notcurses_canopen(nc)){ if(!notcurses_canopen_images(nc)){
return 0; return 0;
} }
int dimy, dimx; int dimy, dimx;
@ -135,7 +135,10 @@ int view_demo(struct notcurses* nc){
if(ncpl == NULL){ if(ncpl == NULL){
return -1; return -1;
} }
int ret = view_video_demo(nc); int ret = 0;
if(notcurses_canopen_videos(nc)){
ret |= view_video_demo(nc);
}
ncplane_destroy(ncpl); ncplane_destroy(ncpl);
return ret; return ret;
} }

View File

@ -96,7 +96,7 @@ perframecb(struct notcurses* nc, struct ncvisual* ncv __attribute__ ((unused)),
} }
int xray_demo(struct notcurses* nc){ int xray_demo(struct notcurses* nc){
if(!notcurses_canopen(nc)){ if(!notcurses_canopen_videos(nc)){
return 0; return 0;
} }
int dimx, dimy; int dimx, dimy;

View File

@ -363,7 +363,11 @@ void ncvisual_destroy(ncvisual* ncv){
} }
} }
bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){ bool notcurses_canopen_images(const notcurses* nc __attribute__ ((unused))){
return true;
}
bool notcurses_canopen_videos(const notcurses* nc __attribute__ ((unused))){
return true; return true;
} }
@ -785,7 +789,11 @@ int ncvisual_init(int loglevel){
} // extern "C" } // extern "C"
#else // built without ffmpeg #else // built without ffmpeg
#ifndef USE_OIIO // built without ffmpeg or oiio #ifndef USE_OIIO // built without ffmpeg or oiio
bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){ bool notcurses_canopen_images(const notcurses* nc __attribute__ ((unused))){
return false;
}
bool notcurses_canopen_videos(const notcurses* nc __attribute__ ((unused))){
return false; return false;
} }
@ -840,10 +848,14 @@ void ncvisual_destroy(ncvisual* ncv){
} }
#else #else
#ifdef USE_OIIO #ifdef USE_OIIO
bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){ bool notcurses_canopen_images(const notcurses* nc __attribute__ ((unused))){
return true; return true;
} }
bool notcurses_canopen_videos(const notcurses* nc __attribute__ ((unused))){
return false; // too slow for reliable use at the moment
}
static ncvisual* static ncvisual*
ncvisual_open(const char* filename, nc_err_e* err){ ncvisual_open(const char* filename, nc_err_e* err){
*ncerr = NCERR_SUCCESS; *ncerr = NCERR_SUCCESS;

View File

@ -82,7 +82,7 @@ int main(void){
channels_set_bg_alpha(&sopts.bgchannels, CELL_ALPHA_BLEND); channels_set_bg_alpha(&sopts.bgchannels, CELL_ALPHA_BLEND);
struct ncplane* n = notcurses_stdplane(nc); struct ncplane* n = notcurses_stdplane(nc);
if(notcurses_canopen(nc)){ if(notcurses_canopen_images(nc)){
nc_err_e err; nc_err_e err;
struct ncvisual* ncv = ncplane_visual_open(n, "../data/covid19.jpg", &err); struct ncvisual* ncv = ncplane_visual_open(n, "../data/covid19.jpg", &err);
if(!ncv){ if(!ncv){

View File

@ -83,7 +83,7 @@ int main(void){
channels_set_bg_alpha(&sopts.bgchannels, CELL_ALPHA_BLEND); channels_set_bg_alpha(&sopts.bgchannels, CELL_ALPHA_BLEND);
struct ncplane* n = notcurses_stdplane(nc); struct ncplane* n = notcurses_stdplane(nc);
if(notcurses_canopen(nc)){ if(notcurses_canopen_images(nc)){
nc_err_e err; nc_err_e err;
struct ncvisual* ncv = ncplane_visual_open(n, "../data/changes.jpg", &err); struct ncvisual* ncv = ncplane_visual_open(n, "../data/changes.jpg", &err);
if(!ncv){ if(!ncv){

View File

@ -178,7 +178,7 @@ auto main(int argc, char** argv) -> int {
NCScale stretchmode; NCScale stretchmode;
auto nonopt = handle_opts(argc, argv, NotCurses::default_notcurses_options, &timescale, &stretchmode); auto nonopt = handle_opts(argc, argv, NotCurses::default_notcurses_options, &timescale, &stretchmode);
NotCurses nc; NotCurses nc;
if(!nc.can_open()){ if(!nc.can_open_images()){
nc.stop(); nc.stop();
std::cerr << "Notcurses was compiled without multimedia support\n"; std::cerr << "Notcurses was compiled without multimedia support\n";
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -16,12 +16,13 @@ TEST_CASE("Visual") {
REQUIRE(ncp_); REQUIRE(ncp_);
#ifndef USE_MULTIMEDIA #ifndef USE_MULTIMEDIA
SUBCASE("LibavDisabled"){ SUBCASE("VisualDisabled"){
REQUIRE(!notcurses_canopen(nc_)); REQUIRE(!notcurses_canopen_images(nc_));
REQUIRE(!notcurses_canopen_videos(nc_));
} }
#else #else
SUBCASE("LibavEnabled"){ SUBCASE("ImagesEnabled"){
REQUIRE(notcurses_canopen(nc_)); REQUIRE(notcurses_canopen_images(nc_));
} }
SUBCASE("LoadImageCreatePlane") { SUBCASE("LoadImageCreatePlane") {
@ -87,40 +88,44 @@ TEST_CASE("Visual") {
} }
SUBCASE("LoadVideo") { SUBCASE("LoadVideo") {
nc_err_e ncerr = NCERR_SUCCESS; if(notcurses_canopen_videos(nc_)){
int dimy, dimx; nc_err_e ncerr = NCERR_SUCCESS;
ncplane_dim_yx(ncp_, &dimy, &dimx); int dimy, dimx;
auto ncv = ncplane_visual_open(ncp_, find_data("notcursesI.avi"), &ncerr); ncplane_dim_yx(ncp_, &dimy, &dimx);
REQUIRE(ncv); auto ncv = ncplane_visual_open(ncp_, find_data("notcursesI.avi"), &ncerr);
CHECK(NCERR_SUCCESS == ncerr); REQUIRE(ncv);
for(;;){ // run at the highest speed we can CHECK(NCERR_SUCCESS == ncerr);
ncerr = ncvisual_decode(ncv); for(;;){ // run at the highest speed we can
if(NCERR_EOF == ncerr){ ncerr = ncvisual_decode(ncv);
break; if(NCERR_EOF == ncerr){
break;
}
CHECK(NCERR_SUCCESS == ncerr);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
CHECK(0 < ncvisual_render(ncv, 0, 0, -1, -1));
CHECK(0 == notcurses_render(nc_));
} }
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoCreatePlane") {
if(notcurses_canopen_videos(nc_)){
nc_err_e ncerr = NCERR_SUCCESS;
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(nc_, find_data("notcursesI.avi"), &ncerr, 0, 0, NCSCALE_STRETCH);
REQUIRE(ncv);
CHECK(NCERR_SUCCESS == ncerr);
ncerr = ncvisual_decode(ncv);
CHECK(NCERR_SUCCESS == ncerr); CHECK(NCERR_SUCCESS == ncerr);
/*CHECK(dimy * 2 == frame->height); /*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */ CHECK(dimx == frame->width); FIXME */
CHECK(0 < ncvisual_render(ncv, 0, 0, -1, -1)); CHECK(0 < ncvisual_render(ncv, 0, 0, -1, -1));
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
ncvisual_destroy(ncv);
} }
ncvisual_destroy(ncv);
}
SUBCASE("LoadVideoCreatePlane") {
nc_err_e ncerr = NCERR_SUCCESS;
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(nc_, find_data("notcursesI.avi"), &ncerr, 0, 0, NCSCALE_STRETCH);
REQUIRE(ncv);
CHECK(NCERR_SUCCESS == ncerr);
ncerr = ncvisual_decode(ncv);
CHECK(NCERR_SUCCESS == ncerr);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
CHECK(0 < ncvisual_render(ncv, 0, 0, -1, -1));
CHECK(0 == notcurses_render(nc_));
ncvisual_destroy(ncv);
} }
#endif #endif