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
|
bool scrolling; // is scrolling enabled? always disabled by default
|
||||||
} ncplane;
|
} 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
|
// current presentation state of the terminal. it is carried across render
|
||||||
// instances. initialize everything to 0 on a terminal reset / startup.
|
// instances. initialize everything to 0 on a terminal reset / startup.
|
||||||
typedef struct renderstate {
|
typedef struct renderstate {
|
||||||
|
117
src/lib/libav.c
117
src/lib/libav.c
@ -2,99 +2,38 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "internal.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){
|
ncplane* ncvisual_plane(ncvisual* ncv){
|
||||||
return ncv->ncp;
|
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){
|
void ncvisual_destroy(ncvisual* ncv){
|
||||||
if(ncv){
|
if(ncv){
|
||||||
#ifdef USE_FFMPEG
|
#ifdef USE_FFMPEG
|
||||||
|
@ -1,8 +1,58 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#ifdef USE_OIIO
|
#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))){
|
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){
|
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;
|
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){
|
char* ncvisual_subtitle(const ncvisual* ncv){
|
||||||
(void)ncv;
|
(void)ncv;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user