[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