mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-18 03:25:55 +00:00
hide ffmpeg ncvisual definition
This commit is contained in:
parent
ddfa62db70
commit
5bae4f93b8
90
src/lib/blit.c
Normal file
90
src/lib/blit.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include "internal.h"
|
||||
|
||||
// alpha comes to us 0--255, but we have only 3 alpha values to map them to.
|
||||
// settled on experimentally.
|
||||
static inline bool
|
||||
ffmpeg_trans_p(bool bgr, unsigned char alpha){
|
||||
if(!bgr && alpha < 192){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// RGBA/BGRx blitter. For incoming BGRx (no transparency), bgr == true.
|
||||
static inline int
|
||||
tria_blit(ncplane* nc, int placey, int placex, int linesize, const void* data,
|
||||
int begy, int begx, int leny, int lenx, bool bgr){
|
||||
const int bpp = 32;
|
||||
const int rpos = bgr ? 2 : 0;
|
||||
const int bpos = bgr ? 0 : 2;
|
||||
int dimy, dimx, x, y;
|
||||
int visy = begy;
|
||||
int total = 0; // number of cells written
|
||||
ncplane_dim_yx(nc, &dimy, &dimx);
|
||||
// FIXME not going to necessarily be safe on all architectures hrmmm
|
||||
const unsigned char* dat = data;
|
||||
for(y = placey ; visy < (begy + leny) && y < dimy ; ++y, visy += 2){
|
||||
if(ncplane_cursor_move_yx(nc, y, placex)){
|
||||
return -1;
|
||||
}
|
||||
int visx = begx;
|
||||
for(x = placex ; visx < (begx + lenx) && x < dimx ; ++x, ++visx){
|
||||
const unsigned char* rgbbase_up = dat + (linesize * visy) + (visx * bpp / CHAR_BIT);
|
||||
const unsigned char* rgbbase_down = dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT);
|
||||
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_up[0], rgbbase_up[1], rgbbase_up[2], rgbbase_up[3]);
|
||||
cell* c = ncplane_cell_ref_yx(nc, y, x);
|
||||
// use the default for the background, as that's the only way it's
|
||||
// effective in that case anyway
|
||||
c->channels = 0;
|
||||
c->attrword = 0;
|
||||
if(ffmpeg_trans_p(bgr, rgbbase_up[3]) || ffmpeg_trans_p(bgr, rgbbase_down[3])){
|
||||
cell_set_bg_alpha(c, CELL_ALPHA_TRANSPARENT);
|
||||
if(ffmpeg_trans_p(bgr, rgbbase_up[3]) && ffmpeg_trans_p(bgr, rgbbase_down[3])){
|
||||
cell_set_fg_alpha(c, CELL_ALPHA_TRANSPARENT);
|
||||
}else if(ffmpeg_trans_p(bgr, rgbbase_up[3])){ // down has the color
|
||||
if(cell_load(nc, c, "\u2584") <= 0){ // lower half block
|
||||
return -1;
|
||||
}
|
||||
cell_set_fg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
}else{ // up has the color
|
||||
if(cell_load(nc, c, "\u2580") <= 0){ // upper half block
|
||||
return -1;
|
||||
}
|
||||
cell_set_fg_rgb(c, rgbbase_up[rpos], rgbbase_up[1], rgbbase_up[bpos]);
|
||||
}
|
||||
}else{
|
||||
if(memcmp(rgbbase_up, rgbbase_down, 3) == 0){
|
||||
cell_set_fg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
cell_set_bg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
if(cell_load(nc, c, " ") <= 0){ // only need the background
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
cell_set_fg_rgb(c, rgbbase_up[rpos], rgbbase_up[1], rgbbase_up[bpos]);
|
||||
cell_set_bg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
if(cell_load(nc, c, "\u2580") <= 0){ // upper half block
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
++total;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// Blit a flat array 'data' of BGRx 32-bit values to the ncplane 'nc', offset
|
||||
// from the upper left by 'placey' and 'placex'. Each row ought occupy
|
||||
// 'linesize' bytes (this might be greater than lenx * 4 due to padding). A
|
||||
// subregion of the input can be specified with 'begy'x'begx' and 'leny'x'lenx'.
|
||||
int ncblit_bgrx(ncplane* nc, int placey, int placex, int linesize,
|
||||
const void* data, int begy, int begx, int leny, int lenx){
|
||||
return tria_blit(nc, placey, placex, linesize, data,
|
||||
begy, begx, leny, lenx, true);
|
||||
}
|
||||
|
||||
int ncblit_rgba(ncplane* nc, int placey, int placex, int linesize,
|
||||
const void* data, int begy, int begx, int leny, int lenx){
|
||||
return tria_blit(nc, placey, placex, linesize, data,
|
||||
begy, begx, leny, lenx, false);
|
||||
}
|
@ -80,34 +80,6 @@ typedef struct ncplane {
|
||||
bool scrolling; // is scrolling enabled? always disabled by default
|
||||
} ncplane;
|
||||
|
||||
typedef struct ncvisual {
|
||||
struct AVFormatContext* fmtctx;
|
||||
struct AVCodecContext* codecctx; // video codec context
|
||||
struct AVCodecContext* subtcodecctx; // subtitle codec context
|
||||
struct AVFrame* frame;
|
||||
struct AVFrame* oframe;
|
||||
struct AVCodec* codec;
|
||||
struct AVCodecParameters* cparams;
|
||||
struct AVCodec* subtcodec;
|
||||
struct AVPacket* packet;
|
||||
struct SwsContext* swsctx;
|
||||
int packet_outstanding;
|
||||
int dstwidth, dstheight;
|
||||
int stream_index; // match against this following av_read_frame()
|
||||
int sub_stream_index; // subtitle stream index, can be < 0 if no subtitles
|
||||
float timescale; // scale frame duration by this value
|
||||
ncplane* ncp;
|
||||
// if we're creating the plane based off the first frame's dimensions, these
|
||||
// describe where the plane ought be placed, and how it ought be sized. this
|
||||
// path sets ncobj. ncvisual_destroy() ought in that case kill the ncplane.
|
||||
int placex, placey;
|
||||
ncscale_e style; // none, scale, or stretch
|
||||
struct notcurses* ncobj; // set iff this ncvisual "owns" its ncplane
|
||||
#ifdef USE_FFMPEG
|
||||
AVSubtitle subtitle;
|
||||
#endif
|
||||
} ncvisual;
|
||||
|
||||
// current presentation state of the terminal. it is carried across render
|
||||
// instances. initialize everything to 0 on a terminal reset / startup.
|
||||
typedef struct renderstate {
|
||||
|
117
src/lib/libav.c
117
src/lib/libav.c
@ -2,99 +2,38 @@
|
||||
#include "version.h"
|
||||
#include "internal.h"
|
||||
|
||||
typedef struct ncvisual {
|
||||
struct AVFormatContext* fmtctx;
|
||||
struct AVCodecContext* codecctx; // video codec context
|
||||
struct AVCodecContext* subtcodecctx; // subtitle codec context
|
||||
struct AVFrame* frame;
|
||||
struct AVFrame* oframe;
|
||||
struct AVCodec* codec;
|
||||
struct AVCodecParameters* cparams;
|
||||
struct AVCodec* subtcodec;
|
||||
struct AVPacket* packet;
|
||||
struct SwsContext* swsctx;
|
||||
int packet_outstanding;
|
||||
int dstwidth, dstheight;
|
||||
int stream_index; // match against this following av_read_frame()
|
||||
int sub_stream_index; // subtitle stream index, can be < 0 if no subtitles
|
||||
float timescale; // scale frame duration by this value
|
||||
ncplane* ncp;
|
||||
// if we're creating the plane based off the first frame's dimensions, these
|
||||
// describe where the plane ought be placed, and how it ought be sized. this
|
||||
// path sets ncobj. ncvisual_destroy() ought in that case kill the ncplane.
|
||||
int placex, placey;
|
||||
ncscale_e style; // none, scale, or stretch
|
||||
struct notcurses* ncobj; // set iff this ncvisual "owns" its ncplane
|
||||
#ifdef USE_FFMPEG
|
||||
AVSubtitle subtitle;
|
||||
#endif
|
||||
} ncvisual;
|
||||
|
||||
ncplane* ncvisual_plane(ncvisual* ncv){
|
||||
return ncv->ncp;
|
||||
}
|
||||
|
||||
// alpha comes to us 0--255, but we have only 3 alpha values to map them to.
|
||||
// settled on experimentally.
|
||||
static inline bool
|
||||
ffmpeg_trans_p(bool bgr, unsigned char alpha){
|
||||
if(!bgr && alpha < 192){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// RGBA/BGRx blitter. For incoming BGRx (no transparency), bgr == true.
|
||||
static inline int
|
||||
tria_blit(ncplane* nc, int placey, int placex, int linesize, const void* data,
|
||||
int begy, int begx, int leny, int lenx, bool bgr){
|
||||
const int bpp = 32;
|
||||
const int rpos = bgr ? 2 : 0;
|
||||
const int bpos = bgr ? 0 : 2;
|
||||
int dimy, dimx, x, y;
|
||||
int visy = begy;
|
||||
int total = 0; // number of cells written
|
||||
ncplane_dim_yx(nc, &dimy, &dimx);
|
||||
// FIXME not going to necessarily be safe on all architectures hrmmm
|
||||
const unsigned char* dat = data;
|
||||
for(y = placey ; visy < (begy + leny) && y < dimy ; ++y, visy += 2){
|
||||
if(ncplane_cursor_move_yx(nc, y, placex)){
|
||||
return -1;
|
||||
}
|
||||
int visx = begx;
|
||||
for(x = placex ; visx < (begx + lenx) && x < dimx ; ++x, ++visx){
|
||||
const unsigned char* rgbbase_up = dat + (linesize * visy) + (visx * bpp / CHAR_BIT);
|
||||
const unsigned char* rgbbase_down = dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT);
|
||||
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_up[0], rgbbase_up[1], rgbbase_up[2], rgbbase_up[3]);
|
||||
cell* c = ncplane_cell_ref_yx(nc, y, x);
|
||||
// use the default for the background, as that's the only way it's
|
||||
// effective in that case anyway
|
||||
c->channels = 0;
|
||||
c->attrword = 0;
|
||||
if(ffmpeg_trans_p(bgr, rgbbase_up[3]) || ffmpeg_trans_p(bgr, rgbbase_down[3])){
|
||||
cell_set_bg_alpha(c, CELL_ALPHA_TRANSPARENT);
|
||||
if(ffmpeg_trans_p(bgr, rgbbase_up[3]) && ffmpeg_trans_p(bgr, rgbbase_down[3])){
|
||||
cell_set_fg_alpha(c, CELL_ALPHA_TRANSPARENT);
|
||||
}else if(ffmpeg_trans_p(bgr, rgbbase_up[3])){ // down has the color
|
||||
if(cell_load(nc, c, "\u2584") <= 0){ // lower half block
|
||||
return -1;
|
||||
}
|
||||
cell_set_fg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
}else{ // up has the color
|
||||
if(cell_load(nc, c, "\u2580") <= 0){ // upper half block
|
||||
return -1;
|
||||
}
|
||||
cell_set_fg_rgb(c, rgbbase_up[rpos], rgbbase_up[1], rgbbase_up[bpos]);
|
||||
}
|
||||
}else{
|
||||
if(memcmp(rgbbase_up, rgbbase_down, 3) == 0){
|
||||
cell_set_fg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
cell_set_bg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
if(cell_load(nc, c, " ") <= 0){ // only need the background
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
cell_set_fg_rgb(c, rgbbase_up[rpos], rgbbase_up[1], rgbbase_up[bpos]);
|
||||
cell_set_bg_rgb(c, rgbbase_down[rpos], rgbbase_down[1], rgbbase_down[bpos]);
|
||||
if(cell_load(nc, c, "\u2580") <= 0){ // upper half block
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
++total;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// Blit a flat array 'data' of BGRx 32-bit values to the ncplane 'nc', offset
|
||||
// from the upper left by 'placey' and 'placex'. Each row ought occupy
|
||||
// 'linesize' bytes (this might be greater than lenx * 4 due to padding). A
|
||||
// subregion of the input can be specified with 'begy'x'begx' and 'leny'x'lenx'.
|
||||
int ncblit_bgrx(ncplane* nc, int placey, int placex, int linesize,
|
||||
const void* data, int begy, int begx, int leny, int lenx){
|
||||
return tria_blit(nc, placey, placex, linesize, data,
|
||||
begy, begx, leny, lenx, true);
|
||||
}
|
||||
|
||||
int ncblit_rgba(ncplane* nc, int placey, int placex, int linesize,
|
||||
const void* data, int begy, int begx, int leny, int lenx){
|
||||
return tria_blit(nc, placey, placex, linesize, data,
|
||||
begy, begx, leny, lenx, false);
|
||||
}
|
||||
|
||||
void ncvisual_destroy(ncvisual* ncv){
|
||||
if(ncv){
|
||||
#ifdef USE_FFMPEG
|
||||
|
@ -1,8 +1,58 @@
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef USE_OIIO
|
||||
#include <OpenImageIO/imageio.h>
|
||||
typedef struct ncvisual {
|
||||
struct AVFormatContext* fmtctx;
|
||||
struct AVCodecContext* codecctx; // video codec context
|
||||
struct AVCodecContext* subtcodecctx; // subtitle codec context
|
||||
struct AVFrame* frame;
|
||||
struct AVFrame* oframe;
|
||||
struct AVCodec* codec;
|
||||
struct AVCodecParameters* cparams;
|
||||
struct AVCodec* subtcodec;
|
||||
struct AVPacket* packet;
|
||||
struct SwsContext* swsctx;
|
||||
int packet_outstanding;
|
||||
int dstwidth, dstheight;
|
||||
int stream_index; // match against this following av_read_frame()
|
||||
int sub_stream_index; // subtitle stream index, can be < 0 if no subtitles
|
||||
float timescale; // scale frame duration by this value
|
||||
ncplane* ncp;
|
||||
// if we're creating the plane based off the first frame's dimensions, these
|
||||
// describe where the plane ought be placed, and how it ought be sized. this
|
||||
// path sets ncobj. ncvisual_destroy() ought in that case kill the ncplane.
|
||||
int placex, placey;
|
||||
ncscale_e style; // none, scale, or stretch
|
||||
struct notcurses* ncobj; // set iff this ncvisual "owns" its ncplane
|
||||
#ifdef USE_FFMPEG
|
||||
AVSubtitle subtitle;
|
||||
#endif
|
||||
} ncvisual;
|
||||
|
||||
bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
ncvisual* ncplane_visual_open(ncplane* nc, const char* filename, int* averr){
|
||||
auto in = OIIO::ImageInput::open(filename);
|
||||
if(!in){
|
||||
return nullptr;
|
||||
}
|
||||
(void)nc;
|
||||
(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;
|
||||
}
|
||||
|
||||
struct AVFrame* ncvisual_decode(ncvisual* nc, int* averr){
|
||||
@ -31,24 +81,6 @@ int ncvisual_stream(struct notcurses* nc, struct ncvisual* ncv, int* averr,
|
||||
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;
|
||||
}
|
||||
|
||||
char* ncvisual_subtitle(const ncvisual* ncv){
|
||||
(void)ncv;
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user