finish shim ncvisual #1301

This commit is contained in:
nick black 2021-01-19 21:27:22 -05:00 committed by Nick Black
parent 45c389a709
commit 556619c848
4 changed files with 46 additions and 63 deletions

View File

@ -1060,15 +1060,12 @@ int drop_signals(void* nc);
void ncvisual_printbanner(const notcurses* nc); void ncvisual_printbanner(const notcurses* nc);
typedef struct ncvisual_implementation { typedef struct ncvisual_implementation {
int (*ncvisual_init)(int loglevel); void (*ncvisual_printbanner)(const struct notcurses* nc);
int (*ncvisual_decode)(struct ncvisual*);
int (*ncvisual_blit)(struct ncvisual* ncv, int rows, int cols, ncplane* n, int (*ncvisual_blit)(struct ncvisual* ncv, int rows, int cols, ncplane* n,
const struct blitset* bset, int placey, int placex, const struct blitset* bset, int placey, int placex,
int begy, int begx, int leny, int lenx, int begy, int begx, int leny, int lenx,
bool blendcolors); bool blendcolors);
struct ncvisual* (*ncvisual_create)(void); struct ncvisual* (*ncvisual_create)(void);
struct ncvisual* (*ncvisual_from_file)(const char* s);
void (*ncvisual_printbanner)(const struct notcurses* nc);
// ncv constructors other than ncvisual_from_file() need to set up the // ncv constructors other than ncvisual_from_file() need to set up the
// AVFrame* 'frame' according to their own data, which is assumed to // AVFrame* 'frame' according to their own data, which is assumed to
// have been prepared already in 'ncv'. // have been prepared already in 'ncv'.
@ -1078,7 +1075,7 @@ typedef struct ncvisual_implementation {
bool canopen_videos; bool canopen_videos;
} ncvisual_implementation; } ncvisual_implementation;
// overriden by strong symbol in libnotcurses.so if built with multimedia // assigned by libnotcurses.so if linked with multimedia
extern const ncvisual_implementation* visual_implementation extern const ncvisual_implementation* visual_implementation
__attribute__ ((visibility("default"))); __attribute__ ((visibility("default")));

View File

@ -4,15 +4,11 @@
#include "visual-details.h" #include "visual-details.h"
#include "internal.h" #include "internal.h"
const __attribute__ ((weak)) const ncvisual_implementation* visual_implementation = nullptr;
ncvisual_implementation* visual_implementation = nullptr;
auto ncvisual_decode(ncvisual* nc) -> int { auto __attribute__ ((weak))
int ret = -1; ncvisual_decode(ncvisual* nc __attribute__ ((unused))) -> int {
if(visual_implementation){ return -1;
ret = visual_implementation->ncvisual_decode(nc);
}
return ret;
} }
auto ncvisual_blit(ncvisual* ncv, int rows, int cols, ncplane* n, auto ncvisual_blit(ncvisual* ncv, int rows, int cols, ncplane* n,
@ -34,37 +30,30 @@ auto ncvisual_blit(ncvisual* ncv, int rows, int cols, ncplane* n,
return ret; return ret;
} }
// ncv constructors other than ncvisual_from_file() need to set up the
// AVFrame* 'frame' according to their own data, which is assumed to
// have been prepared already in 'ncv'.
auto ncvisual_details_seed(struct ncvisual* ncv) -> void { auto ncvisual_details_seed(struct ncvisual* ncv) -> void {
if(visual_implementation){ if(visual_implementation){
visual_implementation->ncvisual_details_seed(ncv); visual_implementation->ncvisual_details_seed(ncv);
} }
} }
auto ncvisual_init(int loglevel) -> int { auto __attribute__ ((weak))
int ret = 0; // default to success here ncvisual_init(int loglevel __attribute__ ((unused))) -> int {
if(visual_implementation){ return 0;
ret = visual_implementation->ncvisual_init(loglevel);
}
return ret;
} }
auto __attribute__ ((weak)) auto __attribute__ ((weak))
ncvisual_from_file(const char* filename) -> ncvisual* { ncvisual_from_file(const char* filename __attribute__ ((unused))) -> ncvisual* {
ncvisual* ret = nullptr; return nullptr;
if(visual_implementation){
ret = visual_implementation->ncvisual_from_file(filename);
}
return ret;
} }
auto ncvisual_create(void) -> ncvisual* { auto ncvisual_create(void) -> ncvisual* {
ncvisual* ret = nullptr;
if(visual_implementation){ if(visual_implementation){
ret = visual_implementation->ncvisual_create(); return visual_implementation->ncvisual_create();
}else{
ret = new ncvisual{};
} }
return ret; return new ncvisual{};
} }
auto ncvisual_printbanner(const notcurses* nc) -> void { auto ncvisual_printbanner(const notcurses* nc) -> void {
@ -549,11 +538,15 @@ auto ncvisual_from_plane(const ncplane* n, ncblitter_e blit, int begy, int begx,
return ncv; return ncv;
} }
auto ncvisual_details_destroy(ncvisual_details* deets){
if(visual_implementation){
visual_implementation->ncvisual_details_destroy(deets);
}
}
auto ncvisual_destroy(ncvisual* ncv) -> void { auto ncvisual_destroy(ncvisual* ncv) -> void {
if(ncv){ if(ncv){
if(visual_implementation){ ncvisual_details_destroy(ncv->details);
visual_implementation->ncvisual_details_destroy(ncv->details);
}
if(ncv->owndata){ if(ncv->owndata){
free(ncv->data); free(ncv->data);
} }

View File

@ -134,8 +134,7 @@ averr2ncerr(int averr){
return -1; return -1;
} }
static int int ncvisual_decode(ncvisual* nc){
ffmpeg_decode(ncvisual* nc){
if(nc->details->fmtctx == nullptr){ // not a file-backed ncvisual if(nc->details->fmtctx == nullptr){ // not a file-backed ncvisual
return -1; return -1;
} }
@ -280,7 +279,7 @@ auto ffmpeg_details_init(void) -> ncvisual_details* {
return deets; return deets;
} }
auto ffmpeg_create() -> ncvisual* { auto ncvisual_create() -> ncvisual* {
auto nc = new ncvisual{}; auto nc = new ncvisual{};
if((nc->details = ffmpeg_details_init()) == nullptr){ if((nc->details = ffmpeg_details_init()) == nullptr){
delete nc; delete nc;
@ -291,7 +290,7 @@ auto ffmpeg_create() -> ncvisual* {
ncvisual* ncvisual_from_file(const char* filename) { ncvisual* ncvisual_from_file(const char* filename) {
AVStream* st; AVStream* st;
ncvisual* ncv = ffmpeg_create(); ncvisual* ncv = ncvisual_create();
if(ncv == nullptr){ if(ncv == nullptr){
// fprintf(stderr, "Couldn't create %s (%s)\n", filename, strerror(errno)); // fprintf(stderr, "Couldn't create %s (%s)\n", filename, strerror(errno));
return nullptr; return nullptr;
@ -531,7 +530,7 @@ int ffmpeg_blit(ncvisual* ncv, int rows, int cols, ncplane* n,
return 0; return 0;
} }
auto ffmpeg_details_seed(ncvisual* ncv) -> void { auto ncvisual_details_seed(ncvisual* ncv) -> void {
assert(nullptr == ncv->details->oframe); assert(nullptr == ncv->details->oframe);
ncv->details->frame->data[0] = reinterpret_cast<uint8_t*>(ncv->data); ncv->details->frame->data[0] = reinterpret_cast<uint8_t*>(ncv->data);
ncv->details->frame->data[1] = nullptr; ncv->details->frame->data[1] = nullptr;
@ -563,20 +562,20 @@ auto ffmpeg_log_level(int level) -> int{
#endif #endif
} }
auto ffmpeg_init(int loglevel) -> int { auto ncvisual_init(int loglevel) -> int {
av_log_set_level(ffmpeg_log_level(loglevel)); av_log_set_level(ffmpeg_log_level(loglevel));
// FIXME could also use av_log_set_callback() and capture the message... // FIXME could also use av_log_set_callback() and capture the message...
return 0; return 0;
} }
void ffmpeg_printbanner(const notcurses* nc __attribute__ ((unused))){ void ncvisual_printbanner(const notcurses* nc __attribute__ ((unused))){
printf(" avformat %u.%u.%u avutil %u.%u.%u swscale %u.%u.%u\n", printf(" avformat %u.%u.%u avutil %u.%u.%u swscale %u.%u.%u\n",
LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO, LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO,
LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO,
LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO); LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO);
} }
auto ffmpeg_details_destroy(ncvisual_details* deets) -> void { auto ncvisual_details_destroy(ncvisual_details* deets) -> void {
avcodec_close(deets->codecctx); avcodec_close(deets->codecctx);
avcodec_free_context(&deets->codecctx); avcodec_free_context(&deets->codecctx);
av_frame_free(&deets->frame); av_frame_free(&deets->frame);
@ -590,14 +589,11 @@ auto ffmpeg_details_destroy(ncvisual_details* deets) -> void {
} }
const static ncvisual_implementation ffmpeg_impl = { const static ncvisual_implementation ffmpeg_impl = {
.ncvisual_init = ffmpeg_init, .ncvisual_printbanner = ncvisual_printbanner,
.ncvisual_decode = ffmpeg_decode,
.ncvisual_blit = ffmpeg_blit, .ncvisual_blit = ffmpeg_blit,
.ncvisual_create = ffmpeg_create, .ncvisual_create = ncvisual_create,
.ncvisual_from_file = ncvisual_from_file, .ncvisual_details_seed = ncvisual_details_seed,
.ncvisual_printbanner = ffmpeg_printbanner, .ncvisual_details_destroy = ncvisual_details_destroy,
.ncvisual_details_seed = ffmpeg_details_seed,
.ncvisual_details_destroy = ffmpeg_details_destroy,
.canopen_images = true, .canopen_images = true,
.canopen_videos = true, .canopen_videos = true,
}; };

View File

@ -28,14 +28,14 @@ oiio_details_init(void) -> ncvisual_details* {
} }
static inline auto static inline auto
oiio_details_destroy(ncvisual_details* deets) -> void { ncvisual_details_destroy(ncvisual_details* deets) -> void {
if(deets->image){ if(deets->image){
deets->image->close(); deets->image->close();
} }
delete deets; delete deets;
} }
auto oiio_create() -> ncvisual* { auto ncvisual_create() -> ncvisual* {
auto nc = new ncvisual{}; auto nc = new ncvisual{};
if((nc->details = oiio_details_init()) == nullptr){ if((nc->details = oiio_details_init()) == nullptr){
delete nc; delete nc;
@ -44,8 +44,8 @@ auto oiio_create() -> ncvisual* {
return nc; return nc;
} }
ncvisual* oiio_from_file(const char* filename) { ncvisual* ncvisual_from_file(const char* filename) {
ncvisual* ncv = oiio_create(); ncvisual* ncv = ncvisual_create();
if(ncv == nullptr){ if(ncv == nullptr){
return nullptr; return nullptr;
} }
@ -252,32 +252,29 @@ auto ncvisual_rotate(ncvisual* ncv, double rads) -> int {
} }
*/ */
auto oiio_details_seed(ncvisual* ncv) -> void { auto ncvisual_details_seed(ncvisual* ncv) -> void {
(void)ncv; (void)ncv;
// FIXME? // FIXME?
} }
int oiio_init(int loglevel) { int ncvisual_init(int loglevel __attribute__ ((unused))) {
// FIXME set OIIO global attribute "debug" based on loglevel // FIXME set OIIO global attribute "debug" based on loglevel
(void)loglevel;
// FIXME check OIIO_VERSION_STRING components against linked openimageio_version() // FIXME check OIIO_VERSION_STRING components against linked openimageio_version()
return 0; // allow success here return 0; // allow success here
} }
// FIXME would be nice to have OIIO::attributes("libraries") in here // FIXME would be nice to have OIIO::attributes("libraries") in here
void oiio_printbanner(const notcurses* nc __attribute__ ((unused))){ void ncvisual_printbanner(const notcurses* nc __attribute__ ((unused))){
printf(" openimageio %s\n", OIIO_VERSION_STRING); printf(" openimageio %s\n", OIIO_VERSION_STRING);
} }
const static ncvisual_implementation oiio_impl = { const static ncvisual_implementation oiio_impl = {
.ncvisual_init = oiio_init, .ncvisual_printbanner = ncvisual_printbanner,
.ncvisual_decode = oiio_decode,
.ncvisual_blit = oiio_blit, .ncvisual_blit = oiio_blit,
.ncvisual_create = oiio_create, .ncvisual_create = ncvisual_create,
.ncvisual_from_file = oiio_from_file, .ncvisual_details_seed = ncvisual_details_seed,
.ncvisual_printbanner = oiio_printbanner, .ncvisual_details_destroy = ncvisual_details_destroy,
.ncvisual_details_seed = oiio_details_seed, .ncvisual_decode = oiio_decode,
.ncvisual_details_destroy = oiio_details_destroy,
.canopen_images = true, .canopen_images = true,
.canopen_videos = false, .canopen_videos = false,
}; };