From patchwork Thu Oct 14 11:06:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Zhao Zhili X-Patchwork-Id: 31108 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2084:0:0:0:0 with SMTP id a4csp7035050ioa; Thu, 14 Oct 2021 04:07:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwfACNzCJ7zqxOF2fyEDxTC24UCPsGG+nq+nTneRUtPIjqVzHZ64S2ILygzR89FWAV+K/gz X-Received: by 2002:a05:6402:11c9:: with SMTP id j9mr7630390edw.373.1634209619873; Thu, 14 Oct 2021 04:06:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634209619; cv=none; d=google.com; s=arc-20160816; b=fpHfM0EC9MSsB4jqG6opURGhctUiKJ+b08FteQbyvBOzWPuKXgM/tm6Amcf18zvh3m 9zSzVnUFyYZrfaFgXJapLne7Jpw52NDxh8ciyR4nhdLHo1VZI+AxTdwgE0nyiLcNcYpX zrWzlnOheAshA7WwUm1Hyj2wRzzpsAKo90nfK+gvJMqKANR94Gl3lMB1xHSKG/UF6oHE mecGZqkAL9Z+k3HcvB+kbmFx8+PAtvtRtNmTqF1E4P+FN6K1iVCFSR4GDqTwxZQ9ynah vdEz46aVGIWpmDCgBpt6jPKRpzVahxVMh8lnb0A4SaPKT8KLEXMRUXl0anHNb/jmxgQs hkyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:to:date:mime-version:from:message-id :dkim-signature:delivered-to; bh=qTuf5wDvaG+bFphvCV8rlwK0FVZm5r7eYRY1Gss9Sbw=; b=Zc4+MLacMjEM2ed++VPWzHb0/HH9jaYXTf/Ei0uFOrHu5QQjTraQ2BLk2X2TcUSOby nF4TnvKFijQ1zOey+lUvdd7sMz/O1QAX4EGYOS88XcbUrIEj46UsNhvS5f1x4cnTo9Ec Ikz2Na7SdpDU6WAqEBbhEUlTpCA9rIu1PSVMzgvcAcqOofEr6Coon6CKPrDjqZUrKnGT Sv48Bh2G8rmhkDD1zflD4iA6tKtVIJBpbiyMDBcz2hNCEb/EQ/Zcq8Qywd8uToipzoDX NpZddEV9ZOcPxk/kTDMh7jrcLwW5XSlH9kb6Of2gqLLqAIlVaXflHBGw5wtuKntEKhXa IS8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@foxmail.com header.s=s201512 header.b=v4eRYBVU; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=foxmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id v23si3185000ejo.762.2021.10.14.04.06.57; Thu, 14 Oct 2021 04:06:59 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@foxmail.com header.s=s201512 header.b=v4eRYBVU; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=foxmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B30AA68A75A; Thu, 14 Oct 2021 14:06:53 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from out203-205-251-59.mail.qq.com (out203-205-251-59.mail.qq.com [203.205.251.59]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 540FF6806E2 for ; Thu, 14 Oct 2021 14:06:44 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foxmail.com; s=s201512; t=1634209601; bh=Ze5jk8Q2iQJ64TCCDoATo1C+NUCGSXrEdqdb8I+1+DU=; h=From:Subject:Date:To; b=v4eRYBVUkO7qawpywW7Rc6Zz9B3kuoV+eF1N5Bn/jCjlqQOMFAuNne1dHAAT8jXAg 6RV5KjJps5m9l1RhGWFb6yReG7Sjydlz/Tb3EGArP8CMmO3HXVVjKaQVTYYw5tFLuo NzTFtAKKfZS4S96/T0rmH+9PnU16s3CQ1Ynz2sDI= Received: from [192.168.255.10] ([113.108.77.51]) by newxmesmtplogicsvrsza28.qq.com (NewEsmtp) with SMTP id 1A824AEC; Thu, 14 Oct 2021 19:06:40 +0800 X-QQ-mid: xmsmtpt1634209600th5cqd06l Message-ID: X-QQ-XMAILINFO: OcXqolb0XZr4QqkBn3CP0JStt+xTyTkqfTjVy84mXVGbN21spug0ifSwU0NDZ2 v60NslV5VBkmii4V9OX/sqIJMWlx9KeW2Fkuz8eE/LPRRNT/oqacEzbTLKiR3INdY5/8Jax3BJw4 Cx1fKM45tgeDvvskPQVPm1ewFH3o+l8A77ARzYyToLI2rT/8PJlDIQEDk8vJ7W4XFlpsAzXMGmu+ Un0FDYsb9uc117NW6ctcRTPDvx8nhTFwE4TTbZqpuo2CvebM+kpXWfrni670YCqaTZfQ3aq2eigh atIF5gWIThCpkxO00qIbz5wrOkfV6Emw6O6MbWp0qG4JHxmzV2kUikJadtY/zITR/9aF+PEbBm8n EYrkiP9V6cJ7aI5uF5QrIbbXKBdR9o3biGTgGhRz41t0T6akbB8THIXlpJ+0Zyf4b+eKHeb4uJO7 K877XEI8dyichHpQ9hDhYH3ZvewmFwrFKLjtJ4Cp1T/GiiKYN0Gez3UKk2jfgsDJcsgN70jeUI4U UVvvHb9qB+p9aSuuUY/68ffcjbm95zVofPuA7QR4bAmoTodnqkbw5HMj35ihDqzNwIPz79l5OfWf 70d3JI00/e3wbiM6UQxtWPuH+BTqtlCdhHrAvXosCtscq7FuLTBjBPHfGLwRhUfLATXXiqzywBsJ d6iaPm31RnBO2xSabHypJm5HmEaI/fh23eRxzWxED7Sgu6eIuofxXIck5s+C4+nrj3oK1FOdWx9s SoWmtjfHK9jBsn13fD0BlFP2M6pZW/y/LeuoFogOqCklIbomadJmQ5kY5n8QgzezDj3oAu0ySvlC v2Q5un5/PyAuYUlzp23iXgTUCGNmzDt3NSU4rZpjF4Al3rc4zNDlF9 From: =?utf-8?b?InpoaWxpemhhbyjotbXlv5fnq4spIg==?= Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.60.0.2.21\)) X-OQ-MSGID: <7E57EE06-D6BC-4974-873E-E5CF526E06DD@foxmail.com> Date: Thu, 14 Oct 2021 19:06:48 +0800 To: FFmpeg development discussions and patches X-Mailer: Apple Mail (2.3654.60.0.2.21) Subject: [FFmpeg-devel] [share a stupid and fun patch] avformat: add a fileptr protocol X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: QvLWAS/7/7aq 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"