From: Shiqi Zhu <hiccupzhu@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Cc: Shiqi Zhu <hiccupzhu@gmail.com>
Subject: [FFmpeg-devel] [PATCH] avfilter: add sdlvsink for video display
Date: Thu, 6 Jun 2024 19:51:00 +0800
Message-ID: <20240606115100.44233-1-hiccupzhu@gmail.com> (raw)
Signed-off-by: Shiqi Zhu <hiccupzhu@gmail.com>
---
configure | 1 +
libavfilter/Makefile | 1 +
libavfilter/allfilters.c | 1 +
libavfilter/vsink_sdlvsink.c | 142 +++++++++++++++++++++++++++++++++++
4 files changed, 145 insertions(+)
create mode 100644 libavfilter/vsink_sdlvsink.c
diff --git a/configure b/configure
index 6c5b8aab9a..968b5c8912 100755
--- a/configure
+++ b/configure
@@ -3977,6 +3977,7 @@ xstack_qsv_filter_deps="libmfx"
xstack_qsv_filter_select="qsvvpp"
pad_vaapi_filter_deps="vaapi_1"
drawbox_vaapi_filter_deps="vaapi_1"
+sdlvsink_filter_deps="sdl2"
# examples
avio_http_serve_files_deps="avformat avutil fork"
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 5992fd161f..feac6b464d 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -616,6 +616,7 @@ OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_ZONEPLATE_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o
+OBJS-$(CONFIG_SDLVSINK_FILTER) += vsink_sdlvsink.o
# multimedia filters
OBJS-$(CONFIG_A3DSCOPE_FILTER) += avf_a3dscope.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index c532682fc2..d5f942ffb5 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -579,6 +579,7 @@ extern const AVFilter ff_vsrc_yuvtestsrc;
extern const AVFilter ff_vsrc_zoneplate;
extern const AVFilter ff_vsink_nullsink;
+extern const AVFilter ff_vsink_sdlvsink;
/* multimedia filters */
extern const AVFilter ff_avf_a3dscope;
diff --git a/libavfilter/vsink_sdlvsink.c b/libavfilter/vsink_sdlvsink.c
new file mode 100644
index 0000000000..630f719c7e
--- /dev/null
+++ b/libavfilter/vsink_sdlvsink.c
@@ -0,0 +1,142 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avfilter.h"
+#include "internal.h"
+#include "libavutil/internal.h"
+#include <SDL2/SDL.h>
+#include <unistd.h>
+
+typedef struct {
+ SDL_Window *window;
+ SDL_Renderer *render;
+ SDL_Texture *texture;
+} SDLVideoContext;
+
+static int init(AVFilterContext *ctx)
+{
+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
+ {
+ av_log(ctx, AV_LOG_ERROR, "SDL2 could not initialize! %s\n", SDL_GetError());
+ return -ENOMEM;
+ }
+
+ SDL_PollEvent(NULL);
+ SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
+
+ return 0;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+ SDLVideoContext *sink = ctx->priv;
+
+ if (sink->texture) {
+ SDL_DestroyTexture(sink->texture);
+ sink->texture = NULL;
+ }
+
+ if (sink->render) {
+ SDL_DestroyRenderer(sink->render);
+ sink->render = NULL;
+ }
+
+ if (sink->window) {
+ SDL_DestroyWindow(sink->window);
+ sink->window = NULL;
+ }
+
+ SDL_Quit();
+}
+
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
+{
+ AVFilterContext *ctx = link->dst;
+ SDLVideoContext *sink = ctx->priv;
+ SDL_RendererInfo renderer_info;
+
+ if (!sink->window) {
+ sink->window = SDL_CreateWindow("YUV Player",
+ SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
+ frame->width, frame->height, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
+ if (!sink->window) {
+ av_log(ctx, AV_LOG_ERROR, "SDL2 could not create window %s\n", SDL_GetError());
+ return -ENOMEM;
+ }
+ }
+
+ if (!sink->render) {
+ sink->render = SDL_CreateRenderer(sink->window, -1, 0);
+ if (!sink->render) {
+ av_log(ctx, AV_LOG_ERROR, "SDL2 could not create render %s\n", SDL_GetError());
+ return -ENOMEM;
+ }
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+
+ SDL_GetRendererInfo(sink->render, &renderer_info);
+ av_log(ctx, AV_LOG_INFO, "sdl2 renderer name:%s\n", renderer_info.name);
+ }
+
+ if (!sink->texture) {
+ sink->texture = SDL_CreateTexture(sink->render, SDL_PIXELFORMAT_IYUV,
+ SDL_TEXTUREACCESS_STREAMING, frame->width, frame->height);
+ if (!sink->texture) {
+ av_log(ctx, AV_LOG_ERROR, "create texture failed %s\n", SDL_GetError());
+ return -EINVAL;
+ }
+ }
+
+ SDL_UpdateYUVTexture(sink->texture, NULL,
+ frame->data[0], frame->linesize[0],
+ frame->data[1], frame->linesize[1],
+ frame->data[2], frame->linesize[2]);
+
+ SDL_RenderClear(sink->render);
+
+ SDL_RenderCopy(sink->render, sink->texture, NULL, NULL);
+ SDL_RenderPresent(sink->render);
+
+ av_frame_free(&frame);
+
+ return 0;
+}
+
+static const AVFilterPad avfilter_vsink_sdlvsink_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .filter_frame = filter_frame,
+ },
+};
+
+static const AVFilterPad avfilter_vsink_sdlvsink_outputs[] = {
+ {
+ .name = NULL,
+ .type = AVMEDIA_TYPE_VIDEO,
+ },
+};
+
+const AVFilter ff_vsink_sdlvsink = {
+ .name = "sdlvsink",
+ .description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input video."),
+ .priv_size = sizeof(SDLVideoContext),
+ .init = init,
+ .uninit = uninit,
+ FILTER_INPUTS(avfilter_vsink_sdlvsink_inputs),
+ FILTER_OUTPUTS(avfilter_vsink_sdlvsink_outputs),
+};
--
2.34.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-request@ffmpeg.org with subject "unsubscribe".
next reply other threads:[~2024-06-06 11:51 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-06 11:51 Shiqi Zhu [this message]
2024-06-06 12:20 ` Zhao Zhili
2024-06-07 2:12 ` Hiccup Zhu
2024-06-07 2:32 ` Zhao Zhili
2024-06-07 3:33 ` Shiqi Zhu
2024-06-07 6:45 ` Rémi Denis-Courmont
2024-06-07 9:53 ` Michael Niedermayer
2024-06-07 10:46 ` Anton Khirnov
2024-06-07 11:54 ` Rémi Denis-Courmont
2024-06-11 13:13 ` Shiqi Zhu
2024-06-12 19:52 ` Stefano Sabatini
2024-06-12 20:14 ` Paul B Mahol
2024-06-13 1:49 ` Shiqi Zhu
2024-06-13 1:54 ` Shiqi Zhu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240606115100.44233-1-hiccupzhu@gmail.com \
--to=hiccupzhu@gmail.com \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git