Just share a patch, not meant for merge. Basically, the patch adds a new protocol which looks like fd:// or pipe:, but deals with FILE *.
You may ask why? It’s useless if the FILE *ptr is a regular one, unless combined with FILE * open_memstream(char **bufp, size_t *sizep); FILE * fmemopen(void *restrict *buf, size_t size, const char * restrict mode); Then you can read or write to memory directly. For example: diff --git a/fftools/ffplay.c b/fftools/ffplay.c index ccea0e4578..e59d524602 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -3554,7 +3554,16 @@ static void opt_input_file(void *optctx, const char *filename) } if (!strcmp(filename, "-")) filename = "pipe:"; - input_filename = filename; + + // This part is stupid + FILE *file = fopen(filename, "rb"); + uint8_t *buf = malloc(128 << 20); + size_t size = fread(buf, 1, 128 << 20, file); + fclose(file); + + // This part is interesting + file = fmemopen(buf, size, "rb"); + asprintf(&input_filename, "fileptr:%p", file); } static int opt_codec(void *optctx, const char *opt, const char *arg) For writing to memory, we have avio_open_dyn_buf(). For reading from meory, we have data_uri. avio callback can handle all kinds of cases. Still, I think the polymorphism of FILE * is interesting. — libavformat/Makefile | 1 + libavformat/file.c | 84 +++++++++++++++++++++++++++++++++++++++++ libavformat/protocols.c | 1 + 3 files changed, 86 insertions(+) diff --git a/libavformat/Makefile b/libavformat/Makefile index 8a1b40aafe..047ad55462 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -637,6 +637,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o +OBJS-$(CONFIG_FILEPTR_PROTOCOL) += file.o OBJS-$(CONFIG_PROMPEG_PROTOCOL) += prompeg.o OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o diff --git a/libavformat/file.c b/libavformat/file.c index 9c23f680cd..bdf56a8473 100644 --- a/libavformat/file.c +++ b/libavformat/file.c @@ -412,3 +412,87 @@ const URLProtocol ff_pipe_protocol = { }; #endif /* CONFIG_PIPE_PROTOCOL */ + +#if CONFIG_FILEPTR_PROTOCOL + +typedef struct FilePtrContext { + const AVClass *class; + FILE *file; +} FilePtrContext; + +static int fileptr_open(URLContext *h, const char *filename, int flags) +{ + FilePtrContext *c = h->priv_data; + FILE *file; + av_strstart(filename, "fileptr:", &filename); + + file = (FILE *)strtoll(filename, NULL, 0); + if(!file) { + av_log(h, AV_LOG_INFO, "no FILE *, open stdin/stdout instead\n"); + if (flags & AVIO_FLAG_WRITE) { + file = stdout; + } else { + file = stdin; + } + } + + c->file = file; + return 0; +} + +static int fileptr_read(URLContext *h, unsigned char *buf, int size) +{ + FilePtrContext *c = h->priv_data; + int ret; + + ret = fread(buf, 1, size, c->file); + if (!ret) { + if (feof(c->file)) + return AVERROR_EOF; + else + return AVERROR(EIO); + } + + return ret; +} + +static int fileptr_write(URLContext *h, const unsigned char *buf, int size) +{ + FilePtrContext *c = h->priv_data; + int ret; + + ret = fwrite(buf, 1, size, c->file); + if (ret != size) + return AVERROR(EIO); + + return ret; +} + +static int64_t fileptr_seek(URLContext *h, int64_t pos, int whence) +{ + FilePtrContext *c = h->priv_data; + int ret; + ret = fseeko(c->file, pos, whence); + if (ret == -1) { + return AVERROR(errno); + } + return ftello(c->file); +} + +static const AVClass fileptr_class = { + .class_name = "fileptr", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +const URLProtocol ff_fileptr_protocol = { + .name = "fileptr", + .url_open = fileptr_open, + .url_read = fileptr_read, + .url_write = fileptr_write, + .url_seek = fileptr_seek, + .priv_data_size = sizeof(FilePtrContext), + .priv_data_class = &fileptr_class, +}; + +#endif \ No newline at end of file diff --git a/libavformat/protocols.c b/libavformat/protocols.c index b108aa6c7e..26c065e665 100644 --- a/libavformat/protocols.c +++ b/libavformat/protocols.c @@ -73,6 +73,7 @@ extern const URLProtocol ff_libsrt_protocol; extern const URLProtocol ff_libssh_protocol; extern const URLProtocol ff_libsmbclient_protocol; extern const URLProtocol ff_libzmq_protocol; +extern const URLProtocol ff_fileptr_protocol; #include "libavformat/protocol_list.c" -- 2.31.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".