ncvisual_destroy() implemented

pull/63/head
nick black 5 years ago committed by Nick Black
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 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
// 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
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

@ -2,86 +2,89 @@
#include <libavformat/avformat.h>
#include "notcurses.h"
int notcurses_visual_open(struct notcurses* nc __attribute__ ((unused)),
const char* filename){
AVFormatContext* ps = NULL;
int ret = avformat_open_input(&ps, filename, NULL, NULL);
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){
ncvisual* ncv = ncvisual_create();
if(ncv == NULL){
return NULL;
}
int ret = avformat_open_input(&ncv->fmtctx, filename, NULL, NULL);
if(ret < 0){
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,
av_err2str(ret));
avformat_close_input(&ps);
return ret;
goto err;
}
av_dump_format(ps, 0, filename, false);
AVPacket* packet = av_packet_alloc();
if((ret = av_read_frame(ps, packet)) < 0){
av_dump_format(ncv->fmtctx, 0, filename, false);
if((ncv->packet = av_packet_alloc()) == NULL){
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,
av_err2str(ret));
av_packet_free(&packet);
avformat_close_input(&ps);
return -1;
goto err;
}
AVCodec* codec;
if((ret = av_find_best_stream(ps, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0)) < 0){
if((ret = av_find_best_stream(ncv->fmtctx, AVMEDIA_TYPE_VIDEO, -1, -1, &ncv->codec, 0)) < 0){
fprintf(stderr, "Couldn't find visuals in %s (%s)\n", filename, av_err2str(ret));
av_packet_free(&packet);
avformat_close_input(&ps);
return -1;
goto err;
}
if(codec == NULL){
if(ncv->codec == NULL){
fprintf(stderr, "Couldn't find decoder for %s\n", filename);
av_packet_free(&packet);
avformat_close_input(&ps);
return -1;
goto err;
}
/*
stream = ret;
AVStream* avstream = ps->streams[stream];
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((ncv->codecctx = avcodec_alloc_context3(ncv->codec)) == NULL){
fprintf(stderr, "Couldn't allocate decoder for %s\n", filename);
goto err;
}
*/
AVCodecContext* codecctx = avcodec_alloc_context3(codec);
if((ret = avcodec_open2(codecctx, codec, NULL)) < 0){
if((ret = avcodec_open2(ncv->codecctx, ncv->codec, NULL)) < 0){
fprintf(stderr, "Couldn't open codec for %s (%s)\n", filename, av_err2str(ret));
avcodec_free_context(&codecctx);
av_packet_free(&packet);
avformat_close_input(&ps);
return -1;
goto err;
}
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,
av_err2str(ret));
avcodec_close(codecctx);
avcodec_free_context(&codecctx);
av_packet_free(&packet);
avformat_close_input(&ps);
return -1;
goto err;
}
AVFrame* frame = av_frame_alloc();
if(frame == NULL){
avcodec_close(codecctx);
avcodec_free_context(&codecctx);
av_packet_free(&packet);
avformat_close_input(&ps);
return -1;
if((ncv->frame = av_frame_alloc()) == NULL){
fprintf(stderr, "Couldn't allocate frame for %s\n", filename);
goto err;
}
return ncv;
// FIXME
avcodec_close(codecctx);
avcodec_free_context(&codecctx);
av_frame_free(&frame);
av_packet_free(&packet);
avformat_close_input(&ps);
return 0;
err:
ncvisual_destroy(ncv);
return NULL;
}

Loading…
Cancel
Save