[Libav-user] av_buffersink_get_frame(): Resource temporarily unavailable

Gianluca Cannata gcannata23 at gmail.com
Tue Jun 25 17:53:16 EEST 2024


Good afternoon,

I am trying to resize a JPEG image with libplacebo and zscale filter using
ffmpeg C API but I keep getting the error in the subject of the email.

This is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersrc.h>
#include <libavfilter/buffersink.h>
#include <libavutil/imgutils.h>
#include <libavutil/pixfmt.h>

int main(int argc, char **argv)
{
    if (argc != 4) {
        fprintf(stderr, "usage: %s <filename> <src_width> <src_height>\n",
argv[0]);
        exit(EXIT_FAILURE);
    }

    const char *filename = argv[1];
    const size_t src_width = (size_t) atol(argv[2]);
    const size_t src_height = (size_t) atol(argv[3]);
    char libav_error[128] = { };
    int libav_ret = 0;

    AVFormatContext *fmt_ctx = avformat_alloc_context();
    if (fmt_ctx == NULL) {
        fprintf(stderr, "avformat_alloc_context(): failed\n");
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL))
!= 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avformat_open_input(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    AVCodecContext *dec_ctx;
    AVCodec *dec;

    libav_ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1,
&dec, 0);
    if (libav_ret == AVERROR_STREAM_NOT_FOUND || libav_ret ==
AVERROR_DECODER_NOT_FOUND) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "av_find_best_stream(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    dec_ctx = avcodec_alloc_context3(dec);
    if (dec_ctx == NULL) {
        fprintf(stderr, "avcodec_alloc_context3(): failed\n");
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avcodec_open2(dec_ctx, dec, NULL)) != 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avcodec_open2(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    AVFrame *frame = av_frame_alloc();
    if (frame == NULL) {
        fprintf(stderr, "av_frame_alloc(): failed\n");
        exit(EXIT_FAILURE);
    }

    AVPacket *packet = av_packet_alloc();
    if (packet == NULL) {
        fprintf(stderr, "av_packet_alloc()");
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = av_read_frame(fmt_ctx, packet)) != 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "av_read_frame(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avcodec_send_packet(dec_ctx, packet)) != 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avcodec_send_packet(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avcodec_receive_frame(dec_ctx, frame)) != 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avcodec_receive_frame(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    av_packet_unref(packet);

    AVFilterGraph *filter_graph = NULL;
    AVFilterContext *buffersrc_ctx = NULL;
    AVFilterContext *buffersink_ctx = NULL;

    filter_graph = avfilter_graph_alloc();
    if (filter_graph == NULL) {
        fprintf(stderr, "avfilter_graph_alloc(): failed\n");
        exit(EXIT_FAILURE);
    }

    const AVFilter *buffersrc_filter = avfilter_get_by_name("buffer");
    if (buffersrc_filter == NULL) {
        fprintf(stderr, "avfilter_get_by_name('buffer'): failed\n");
        exit(EXIT_FAILURE);
    }
    const AVFilter *buffersink_filter = avfilter_get_by_name("buffersink");
    if (buffersink_filter == NULL) {
        fprintf(stderr, "avfilter_get_by_name('buffersink'): failed\n");
        exit(EXIT_FAILURE);
    }

    char buffersrc_args[512];
    snprintf(buffersrc_args, sizeof(buffersrc_args),
"video_size=%ldx%ld:pix_fmt=%d:time_base=1/25", src_width, src_height,
AV_PIX_FMT_YUV422P);

    if ((libav_ret = avfilter_graph_create_filter(&buffersrc_ctx,
buffersrc_filter, "in", buffersrc_args, NULL, filter_graph)) < 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avfilter_graph_create_filter(): %s\n",
libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avfilter_graph_create_filter(&buffersink_ctx,
buffersink_filter, "out", NULL, NULL, filter_graph)) < 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avfilter_graph_create_filter(): %s\n",
libav_error);
        exit(EXIT_FAILURE);
    }

    char libplacebo_args[512];
    snprintf(libplacebo_args, sizeof(libplacebo_args),
"format=yuv422p:colorspace=bt470bg:color_primaries=bt709:color_trc=iec61966-2-1:range=pc");
    AVFilterContext *libplacebo_ctx = NULL;
    const AVFilter *libplacebo_filter = avfilter_get_by_name("libplacebo");
    if (libplacebo_filter == NULL) {
        fprintf(stderr, "av_filter_get_by_name('libplacebo'): failed\n");
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avfilter_graph_create_filter(&libplacebo_ctx,
libplacebo_filter, "libplacebo", libplacebo_args, NULL, filter_graph)) < 0)
{
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avfilter_graph_create_filter(): %s\n",
libav_error);
        exit(EXIT_FAILURE);
    }

    char zscale_args[512];
    snprintf(zscale_args, sizeof(zscale_args), "w=%ld:h=%ld", (src_width /
2), (src_height / 2));
    AVFilterContext *zscale_ctx = NULL;
    const AVFilter *zscale_filter = avfilter_get_by_name("zscale");
    if (zscale_filter == NULL) {
        fprintf(stderr, "avfilter_get_by_name('zscale'): failed\n");
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avfilter_graph_create_filter(&zscale_ctx,
zscale_filter, "zscale", zscale_args, NULL, filter_graph)) < 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avfilter_graph_create_filter(): %s\n",
libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avfilter_link(buffersrc_ctx, 0, libplacebo_ctx, 0)) !=
0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avfilter_link(buffersrc_ctx, 0, libplacebo_ctx,
0): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avfilter_link(libplacebo_ctx, 0, zscale_ctx, 0)) != 0)
{
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avfilter_link(libplacebo_ctx, 0, zscale_ctx, 0):
%s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avfilter_link(zscale_ctx, 0, buffersink_ctx, 0)) != 0)
{
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "avfilter_link(zscale_ctx, 0, buffersink_ctx, 0):
%s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = avfilter_graph_config(filter_graph, NULL)) != 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "av_buffersrc_add_frame(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    if ((libav_ret = av_buffersrc_add_frame(buffersrc_ctx, frame)) != 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "av_buffersrc_add_frame(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    AVFrame *filtered_frame = av_frame_alloc();
    if ((libav_ret = av_buffersink_get_frame(buffersink_ctx,
filtered_frame)) != 0) {
        av_strerror(libav_ret, libav_error, sizeof(libav_error));
        fprintf(stderr, "av_buffersink_get_frame(): %s\n", libav_error);
        exit(EXIT_FAILURE);
    }

    printf("w: %d, h: %d, fmt: %d\n", filtered_frame->width,
filtered_frame->height, filtered_frame->format);

    int dst_size = av_image_get_buffer_size(filtered_frame->format,
filtered_frame->width, filtered_frame->height, 1);
    uint8_t *dst_buf = av_malloc(dst_size * sizeof(uint8_t));
    av_image_copy_to_buffer(dst_buf, dst_size, filtered_frame->data,
filtered_frame->linesize, filtered_frame->format, filtered_frame->width,
filtered_frame->height, 1);

    FILE *dst_file = fopen("COPY.JPG", "wb");
    fwrite(dst_buf, sizeof(*dst_buf), 1, dst_file);
    fclose(dst_file);

    av_frame_free(&frame);
    av_frame_free(&filtered_frame);
    avfilter_graph_free(&filter_graph);
    avformat_close_input(&fmt_ctx);
    avformat_free_context(fmt_ctx);

    exit(EXIT_SUCCESS);
}

Thank you in advance

Gianluca
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20240625/819400d4/attachment.htm>


More information about the Libav-user mailing list