From 98d6f120024b6b6ae28f069d6d8061a89d664c8e Mon Sep 17 00:00:00 2001 From: nick black Date: Tue, 26 Nov 2019 20:19:00 -0500 Subject: [PATCH] visual_open: round out libav loading #35 --- src/lib/libav.c | 55 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/src/lib/libav.c b/src/lib/libav.c index 0103a5fcf..cb3834ef3 100644 --- a/src/lib/libav.c +++ b/src/lib/libav.c @@ -2,7 +2,7 @@ #include #include "notcurses.h" -int notcurses_image_open(struct notcurses* nc, const char* filename){ +int notcurses_visual_open(struct notcurses* nc, const char* filename){ AVFormatContext* ps = NULL; int ret = avformat_open_input(&ps, filename, NULL, NULL); if(ret < 0){ @@ -12,7 +12,7 @@ int notcurses_image_open(struct notcurses* nc, const char* filename){ if((ret = avformat_find_stream_info(ps, NULL)) < 0){ fprintf(stderr, "Error extracting stream info from %s (%s)\n", filename, av_err2str(ret)); - avformat_free_context(ps); + avformat_close_input(&ps); return ret; } av_dump_format(ps, 0, filename, false); @@ -21,27 +21,66 @@ av_dump_format(ps, 0, filename, false); fprintf(stderr, "Error reading frame info from %s (%s)\n", filename, av_err2str(ret)); av_packet_free(&packet); - avformat_free_context(ps); + avformat_close_input(&ps); return -1; } - // FIXME need codec object - if((ret = avcodec_send_packet(codec, &packet)) < 0){ + AVCodec* codec; + 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)); + av_packet_free(&packet); + avformat_close_input(&ps); + return -1; + } + if(codec == NULL){ + fprintf(stderr, "Couldn't find decoder for %s\n", filename); + av_packet_free(&packet); + avformat_close_input(&ps); + return -1; + } + /* + 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; + } + */ + 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)); + avcodec_free_context(&codecctx); + av_packet_free(&packet); + avformat_close_input(&ps); + return -1; + } + if((ret = avcodec_send_packet(codecctx, 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_free_context(ps); + avformat_close_input(&ps); return -1; } AVFrame* frame = av_frame_alloc(); if(frame == NULL){ + avcodec_close(codecctx); + avcodec_free_context(&codecctx); av_packet_free(&packet); - avformat_free_context(ps); + avformat_close_input(&ps); return -1; } // FIXME + avcodec_close(codecctx); + avcodec_free_context(&codecctx); av_frame_free(&frame); av_packet_free(&packet); - avformat_free_context(ps); + avformat_close_input(&ps); return 0; }