mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
ncvisual_destroy() implemented
This commit is contained in:
parent
dc6ce9ba90
commit
4b2bf26ee2
@ -18,6 +18,7 @@ API const char* notcurses_version(void);
|
|||||||
|
|
||||||
struct cell; // a coordinate on an ncplane: an EGC plus styling
|
struct cell; // a coordinate on an ncplane: an EGC plus styling
|
||||||
struct ncplane; // a drawable notcurses surface, composed of cells
|
struct ncplane; // a drawable notcurses surface, composed of cells
|
||||||
|
struct ncvisual; // a visual bit of multimedia opened with LibAV
|
||||||
struct notcurses; // notcurses state for a given terminal, composed of ncplanes
|
struct notcurses; // notcurses state for a given terminal, composed of ncplanes
|
||||||
|
|
||||||
// A cell corresponds to a single character cell on some plane, which can be
|
// A cell corresponds to a single character cell on some plane, which can be
|
||||||
@ -427,7 +428,9 @@ ncplane_rounded_box_cells(struct ncplane* n, cell* ul, cell* ur, cell* ll,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// multimedia functionality
|
// multimedia functionality
|
||||||
API int notcurses_visual_open(struct notcurses* nc, const char* filename);
|
API struct ncvisual* notcurses_visual_open(struct notcurses* nc,
|
||||||
|
const char* filename);
|
||||||
|
API void ncvisual_destroy(struct ncvisual* ncv);
|
||||||
|
|
||||||
#undef API
|
#undef API
|
||||||
|
|
||||||
|
123
src/lib/libav.c
123
src/lib/libav.c
@ -2,86 +2,89 @@
|
|||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include "notcurses.h"
|
#include "notcurses.h"
|
||||||
|
|
||||||
int notcurses_visual_open(struct notcurses* nc __attribute__ ((unused)),
|
typedef struct ncvisual {
|
||||||
|
AVFormatContext* fmtctx;
|
||||||
|
AVCodecContext* codecctx;
|
||||||
|
AVFrame* frame;
|
||||||
|
AVCodec* codec;
|
||||||
|
AVPacket* packet;
|
||||||
|
} ncvisual;
|
||||||
|
|
||||||
|
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){
|
||||||
|
avcodec_close(ncv->codecctx);
|
||||||
|
avcodec_free_context(&ncv->codecctx);
|
||||||
|
av_frame_free(&ncv->frame);
|
||||||
|
av_packet_free(&ncv->packet);
|
||||||
|
avformat_close_input(&ncv->fmtctx);
|
||||||
|
free(ncv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ncvisual* notcurses_visual_open(struct notcurses* nc __attribute__ ((unused)),
|
||||||
const char* filename){
|
const char* filename){
|
||||||
AVFormatContext* ps = NULL;
|
ncvisual* ncv = ncvisual_create();
|
||||||
int ret = avformat_open_input(&ps, filename, NULL, NULL);
|
if(ncv == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int ret = avformat_open_input(&ncv->fmtctx, filename, NULL, NULL);
|
||||||
if(ret < 0){
|
if(ret < 0){
|
||||||
fprintf(stderr, "Couldn't open %s (%s)\n", filename, av_err2str(ret));
|
fprintf(stderr, "Couldn't open %s (%s)\n", filename, av_err2str(ret));
|
||||||
return ret;
|
goto err;
|
||||||
}
|
}
|
||||||
if((ret = avformat_find_stream_info(ps, NULL)) < 0){
|
if((ret = avformat_find_stream_info(ncv->fmtctx, NULL)) < 0){
|
||||||
fprintf(stderr, "Error extracting stream info from %s (%s)\n", filename,
|
fprintf(stderr, "Error extracting stream info from %s (%s)\n", filename,
|
||||||
av_err2str(ret));
|
av_err2str(ret));
|
||||||
avformat_close_input(&ps);
|
goto err;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
av_dump_format(ps, 0, filename, false);
|
av_dump_format(ncv->fmtctx, 0, filename, false);
|
||||||
AVPacket* packet = av_packet_alloc();
|
if((ncv->packet = av_packet_alloc()) == NULL){
|
||||||
if((ret = av_read_frame(ps, packet)) < 0){
|
fprintf(stderr, "Couldn't allocate packet for %s\n", filename);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if((ret = av_read_frame(ncv->fmtctx, ncv->packet)) < 0){
|
||||||
fprintf(stderr, "Error reading frame info from %s (%s)\n", filename,
|
fprintf(stderr, "Error reading frame info from %s (%s)\n", filename,
|
||||||
av_err2str(ret));
|
av_err2str(ret));
|
||||||
av_packet_free(&packet);
|
goto err;
|
||||||
avformat_close_input(&ps);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
AVCodec* codec;
|
if((ret = av_find_best_stream(ncv->fmtctx, AVMEDIA_TYPE_VIDEO, -1, -1, &ncv->codec, 0)) < 0){
|
||||||
if((ret = av_find_best_stream(ps, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0)) < 0){
|
|
||||||
fprintf(stderr, "Couldn't find visuals in %s (%s)\n", filename, av_err2str(ret));
|
fprintf(stderr, "Couldn't find visuals in %s (%s)\n", filename, av_err2str(ret));
|
||||||
av_packet_free(&packet);
|
goto err;
|
||||||
avformat_close_input(&ps);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
if(codec == NULL){
|
if(ncv->codec == NULL){
|
||||||
fprintf(stderr, "Couldn't find decoder for %s\n", filename);
|
fprintf(stderr, "Couldn't find decoder for %s\n", filename);
|
||||||
av_packet_free(&packet);
|
goto err;
|
||||||
avformat_close_input(&ps);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
/*
|
if((ncv->codecctx = avcodec_alloc_context3(ncv->codec)) == NULL){
|
||||||
stream = ret;
|
fprintf(stderr, "Couldn't allocate decoder for %s\n", filename);
|
||||||
AVStream* avstream = ps->streams[stream];
|
goto err;
|
||||||
AVCodecContext* codecctx = avstream->codec;
|
|
||||||
AVCodec* codec = avcodec_find_decoder(codecctx->codec_id);
|
|
||||||
if(codec == NULL){
|
|
||||||
fprintf(stderr, "Couldn't find decoder for %s (%s)\n", filename);
|
|
||||||
avcodec_close(codecctx);
|
|
||||||
av_packet_free(&packet);
|
|
||||||
avformat_close_input(&ps);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
*/
|
if((ret = avcodec_open2(ncv->codecctx, ncv->codec, NULL)) < 0){
|
||||||
AVCodecContext* codecctx = avcodec_alloc_context3(codec);
|
|
||||||
if((ret = avcodec_open2(codecctx, codec, NULL)) < 0){
|
|
||||||
fprintf(stderr, "Couldn't open codec for %s (%s)\n", filename, av_err2str(ret));
|
fprintf(stderr, "Couldn't open codec for %s (%s)\n", filename, av_err2str(ret));
|
||||||
avcodec_free_context(&codecctx);
|
goto err;
|
||||||
av_packet_free(&packet);
|
|
||||||
avformat_close_input(&ps);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
if((ret = avcodec_send_packet(codecctx, packet)) < 0){
|
if((ret = avcodec_send_packet(ncv->codecctx, ncv->packet)) < 0){
|
||||||
fprintf(stderr, "Error decoding packet from %s (%s)\n", filename,
|
fprintf(stderr, "Error decoding packet from %s (%s)\n", filename,
|
||||||
av_err2str(ret));
|
av_err2str(ret));
|
||||||
avcodec_close(codecctx);
|
goto err;
|
||||||
avcodec_free_context(&codecctx);
|
|
||||||
av_packet_free(&packet);
|
|
||||||
avformat_close_input(&ps);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
AVFrame* frame = av_frame_alloc();
|
if((ncv->frame = av_frame_alloc()) == NULL){
|
||||||
if(frame == NULL){
|
fprintf(stderr, "Couldn't allocate frame for %s\n", filename);
|
||||||
avcodec_close(codecctx);
|
goto err;
|
||||||
avcodec_free_context(&codecctx);
|
|
||||||
av_packet_free(&packet);
|
|
||||||
avformat_close_input(&ps);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
return ncv;
|
||||||
|
|
||||||
// FIXME
|
err:
|
||||||
avcodec_close(codecctx);
|
ncvisual_destroy(ncv);
|
||||||
avcodec_free_context(&codecctx);
|
return NULL;
|
||||||
av_frame_free(&frame);
|
|
||||||
av_packet_free(&packet);
|
|
||||||
avformat_close_input(&ps);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user