1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

avformat/img2enc: use a AVBPrint buffer for generating the filename

This removes all path length limits from img2enc.

Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
Marton Balint
2025-08-01 23:42:21 +02:00
parent ec64d9b73b
commit c31df899d9

View File

@ -26,6 +26,7 @@
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h"
#include "libavutil/dict.h" #include "libavutil/dict.h"
#include "libavutil/log.h" #include "libavutil/log.h"
#include "libavutil/mem.h" #include "libavutil/mem.h"
@ -142,29 +143,28 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
AVIOContext *pb[4] = {0}; AVIOContext *pb[4] = {0};
char* target[4] = {0}; char* target[4] = {0};
char* tmp[4] = {0}; char* tmp[4] = {0};
char filename[1024];
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(par->format); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(par->format);
int ret, i; int ret, i;
AVDictionary *options = NULL; AVDictionary *options = NULL;
AVBPrint filename;
av_bprint_init(&filename, 0, AV_BPRINT_SIZE_UNLIMITED);
if (img->update) { if (img->update) {
av_strlcpy(filename, s->url, sizeof(filename)); av_bprintf(&filename, "%s", s->url);
} else if (img->use_strftime) { } else if (img->use_strftime) {
time_t now0; time_t now0;
struct tm *tm, tmpbuf; struct tm *tm, tmpbuf;
time(&now0); time(&now0);
tm = localtime_r(&now0, &tmpbuf); tm = localtime_r(&now0, &tmpbuf);
if (!strftime(filename, sizeof(filename), s->url, tm)) { av_bprint_strftime(&filename, s->url, tm);
av_log(s, AV_LOG_ERROR, "Could not get frame filename with strftime\n");
return AVERROR(EINVAL);
}
} else if (img->frame_pts) { } else if (img->frame_pts) {
if (ff_get_frame_filename(filename, sizeof(filename), s->url, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) { if (ff_bprint_get_frame_filename(&filename, s->url, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
av_log(s, AV_LOG_ERROR, "Cannot write filename by pts of the frames."); av_log(s, AV_LOG_ERROR, "Cannot write filename by pts of the frames.");
return AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto fail;
} }
} else if (ff_get_frame_filename(filename, sizeof(filename), s->url, } else if (ff_bprint_get_frame_filename(&filename, s->url,
img->img_number, img->img_number,
AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) { AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
if (img->img_number == img->start_img_number) { if (img->img_number == img->start_img_number) {
@ -172,24 +172,30 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
av_log(s, AV_LOG_WARNING, av_log(s, AV_LOG_WARNING,
"Use a pattern such as %%03d for an image sequence or " "Use a pattern such as %%03d for an image sequence or "
"use the -update option (with -frames:v 1 if needed) to write a single image.\n"); "use the -update option (with -frames:v 1 if needed) to write a single image.\n");
av_strlcpy(filename, s->url, sizeof(filename)); av_bprint_clear(&filename);
av_bprintf(&filename, "%s", s->url);
} else { } else {
av_log(s, AV_LOG_ERROR, "Cannot write more than one file with the same name. Are you missing the -update option or a sequence pattern?\n"); av_log(s, AV_LOG_ERROR, "Cannot write more than one file with the same name. Are you missing the -update option or a sequence pattern?\n");
return AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto fail;
} }
} }
if (!av_bprint_is_complete(&filename)) {
ret = AVERROR(ENOMEM);
goto fail;
}
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
av_dict_copy(&options, img->protocol_opts, 0); av_dict_copy(&options, img->protocol_opts, 0);
if (img->use_rename) { if (img->use_rename) {
tmp[i] = av_asprintf("%s.tmp", filename); tmp[i] = av_asprintf("%s.tmp", filename.str);
target[i] = av_strdup(filename); target[i] = av_strdup(filename.str);
if (!tmp[i] || !target[i]) { if (!tmp[i] || !target[i]) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
} }
} }
if (s->io_open(s, &pb[i], tmp[i] ? tmp[i] : filename, AVIO_FLAG_WRITE, &options) < 0) { if (s->io_open(s, &pb[i], tmp[i] ? tmp[i] : filename.str, AVIO_FLAG_WRITE, &options) < 0) {
av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", tmp[i] ? tmp[i] : filename); av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", tmp[i] ? tmp[i] : filename.str);
ret = AVERROR(EIO); ret = AVERROR(EIO);
goto fail; goto fail;
} }
@ -201,8 +207,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
if (!img->split_planes || i+1 >= desc->nb_components) if (!img->split_planes || i+1 >= desc->nb_components)
break; break;
filename[strlen(filename) - 1] = "UVAx"[i]; filename.str[filename.len - 1] = "UVAx"[i];
} }
av_bprint_finalize(&filename, NULL);
if (img->split_planes) { if (img->split_planes) {
int ysize = par->width * par->height; int ysize = par->width * par->height;
@ -239,6 +246,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
return 0; return 0;
fail: fail:
av_bprint_finalize(&filename, NULL);
av_dict_free(&options); av_dict_free(&options);
for (i = 0; i < FF_ARRAY_ELEMS(pb); i++) { for (i = 0; i < FF_ARRAY_ELEMS(pb); i++) {
av_freep(&tmp[i]); av_freep(&tmp[i]);