* [FFmpeg-devel] [PATCH] fftools/ffplay: migrate to SDL3
@ 2026-01-02 22:41 Marcin Serwin via ffmpeg-devel
2026-01-03 4:41 ` [FFmpeg-devel] " Michael Niedermayer via ffmpeg-devel
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Marcin Serwin via ffmpeg-devel @ 2026-01-02 22:41 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Marcin Serwin
Migrates the FFplay media player to the new SDL version using the
official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
Signed-off-by: Marcin Serwin <marcin@serwin.dev>
---
This is just first iteration but I wanted to make sure if you're interested in
doing the migration and gather some early feedback. With this path I am able to
play some basic video and audio files on my Linux system but I haven't tested it
with other platforms.
configure | 26 +---
fftools/ffplay.c | 283 ++++++++++++++++++--------------------
fftools/ffplay_renderer.c | 12 +-
fftools/ffplay_renderer.h | 2 +-
4 files changed, 150 insertions(+), 173 deletions(-)
diff --git a/configure b/configure
index 301a3e5e3e..e3927fe4ab 100755
--- a/configure
+++ b/configure
@@ -338,7 +338,7 @@ External library support:
--disable-sndio disable sndio support [autodetect]
--disable-schannel disable SChannel SSP, needed for TLS support on
Windows if openssl and gnutls are not used [autodetect]
- --disable-sdl2 disable sdl2 [autodetect]
+ --disable-sdl3 disable sdl3 [autodetect]
--disable-securetransport disable Secure Transport, needed for TLS support
on OSX if openssl and gnutls are not used [autodetect]
--enable-vapoursynth enable VapourSynth demuxer [no]
@@ -1904,7 +1904,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST="
mediafoundation
metal
schannel
- sdl2
+ sdl3
securetransport
sndio
xlib
@@ -4217,7 +4217,7 @@ ffmpeg_select="aformat_filter anull_filter atrim_filter crop_filter
format_filter hflip_filter null_filter rotate_filter
transpose_filter trim_filter vflip_filter"
ffmpeg_suggest="ole32 psapi shell32"
-ffplay_deps="avcodec avformat avfilter swscale swresample sdl2"
+ffplay_deps="avcodec avformat avfilter swscale swresample sdl3"
ffplay_select="crop_filter transpose_filter hflip_filter vflip_filter rotate_filter"
ffplay_suggest="shell32 libplacebo vulkan"
ffprobe_deps="avcodec avformat"
@@ -4562,7 +4562,7 @@ for opt do
do_random ${action#--} $optval
;;
--enable-sdl)
- enable sdl2
+ enable sdl3
;;
--enable-lto*)
lto=-f${opt#--enable-}
@@ -7404,20 +7404,8 @@ if enabled gcrypt; then
fi
fi
-if enabled sdl2; then
- SDL2_CONFIG="${cross_prefix}sdl2-config"
- test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 3.0.0" SDL_events.h SDL_PollEvent
- if disabled sdl2 && "${SDL2_CONFIG}" --version > /dev/null 2>&1; then
- sdl2_cflags=$("${SDL2_CONFIG}" --cflags)
- sdl2_extralibs=$("${SDL2_CONFIG}" --libs)
- test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags &&
- test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x030000" $sdl2_cflags &&
- check_func_headers SDL_events.h SDL_PollEvent $sdl2_extralibs $sdl2_cflags &&
- enable sdl2
- fi
- if test $target_os = "mingw32"; then
- sdl2_extralibs=$(filter_out '-mwindows' $sdl2_extralibs)
- fi
+if enabled sdl3; then
+ test_pkg_config sdl3 "sdl3 >= 3.2.0 sdl3 < 4.0.0" SDL3/SDL_events.h SDL_PollEvent
fi
if enabled decklink; then
@@ -8467,7 +8455,7 @@ HOSTLD_O=$HOSTLD_O
TARGET_EXEC=$target_exec $target_exec_args
TARGET_PATH=$target_path
TARGET_SAMPLES=${target_samples:-\$(SAMPLES)}
-CFLAGS-ffplay=${sdl2_cflags}
+CFLAGS-ffplay=${sdl3_cflags}
CFLAGS_HEADERS=$CFLAGS_HEADERS
LIB_INSTALL_EXTRA_CMD=$LIB_INSTALL_EXTRA_CMD
EXTRALIBS=$extralibs
diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index dcd20e70bc..52d842083c 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -51,8 +51,9 @@
#include "libavfilter/buffersink.h"
#include "libavfilter/buffersrc.h"
-#include <SDL.h>
-#include <SDL_thread.h>
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_main.h>
+#include <SDL3/SDL_thread.h>
#include "cmdutils.h"
#include "ffplay_renderer.h"
@@ -117,8 +118,8 @@ typedef struct PacketQueue {
int64_t duration;
int abort_request;
int serial;
- SDL_mutex *mutex;
- SDL_cond *cond;
+ SDL_Mutex *mutex;
+ SDL_Condition *cond;
} PacketQueue;
#define VIDEO_PICTURE_QUEUE_SIZE 3
@@ -172,8 +173,8 @@ typedef struct FrameQueue {
int max_size;
int keep_last;
int rindex_shown;
- SDL_mutex *mutex;
- SDL_cond *cond;
+ SDL_Mutex *mutex;
+ SDL_Condition *cond;
PacketQueue *pktq;
} FrameQueue;
@@ -190,7 +191,7 @@ typedef struct Decoder {
int pkt_serial;
int finished;
int packet_pending;
- SDL_cond *empty_queue_cond;
+ SDL_Condition *empty_queue_cond;
int64_t start_pts;
AVRational start_pts_tb;
int64_t next_pts;
@@ -245,7 +246,7 @@ typedef struct VideoState {
unsigned int audio_buf1_size;
int audio_buf_index; /* in bytes */
int audio_write_buf_size;
- int audio_volume;
+ float audio_volume;
int muted;
struct AudioParams audio_src;
struct AudioParams audio_filter_src;
@@ -283,7 +284,8 @@ typedef struct VideoState {
PacketQueue videoq;
double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
struct SwsContext *sub_convert_ctx;
- int eof;
+ bool shown;
+ bool eof;
char *filename;
int width, height, xleft, ytop;
@@ -298,7 +300,7 @@ typedef struct VideoState {
int last_video_stream, last_audio_stream, last_subtitle_stream;
- SDL_cond *continue_read_thread;
+ SDL_Condition *continue_read_thread;
} VideoState;
/* options specified by the user */
@@ -356,12 +358,12 @@ static const char *hwaccel = NULL;
static int is_full_screen;
static int64_t audio_callback_time;
-#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
+#define FF_QUIT_EVENT (SDL_EVENT_USER + 2)
static SDL_Window *window;
static SDL_Renderer *renderer;
-static SDL_RendererInfo renderer_info = {0};
-static SDL_AudioDeviceID audio_dev;
+static const SDL_PixelFormat *renderer_texture_formats;
+static SDL_AudioStream *audio_stream;
static VkRenderer *vk_renderer;
@@ -370,15 +372,15 @@ static const struct TextureFormatEntry {
int texture_fmt;
} sdl_texture_format_map[] = {
{ AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 },
- { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 },
- { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 },
- { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 },
+ { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_XRGB4444 },
+ { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_XRGB1555 },
+ { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_XBGR1555 },
{ AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 },
{ AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 },
{ AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 },
{ AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 },
- { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 },
- { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 },
+ { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_XRGB8888 },
+ { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_XBGR8888 },
{ AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 },
{ AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 },
{ AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 },
@@ -433,7 +435,7 @@ static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
q->size += pkt1.pkt->size + sizeof(pkt1);
q->duration += pkt1.pkt->duration;
/* XXX: should duplicate packet data in DV case */
- SDL_CondSignal(q->cond);
+ SDL_SignalCondition(q->cond);
return 0;
}
@@ -477,7 +479,7 @@ static int packet_queue_init(PacketQueue *q)
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
- q->cond = SDL_CreateCond();
+ q->cond = SDL_CreateCondition();
if (!q->cond) {
av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
@@ -505,7 +507,7 @@ static void packet_queue_destroy(PacketQueue *q)
packet_queue_flush(q);
av_fifo_freep2(&q->pkt_list);
SDL_DestroyMutex(q->mutex);
- SDL_DestroyCond(q->cond);
+ SDL_DestroyCondition(q->cond);
}
static void packet_queue_abort(PacketQueue *q)
@@ -514,7 +516,7 @@ static void packet_queue_abort(PacketQueue *q)
q->abort_request = 1;
- SDL_CondSignal(q->cond);
+ SDL_SignalCondition(q->cond);
SDL_UnlockMutex(q->mutex);
}
@@ -555,14 +557,14 @@ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *seria
ret = 0;
break;
} else {
- SDL_CondWait(q->cond, q->mutex);
+ SDL_WaitCondition(q->cond, q->mutex);
}
}
SDL_UnlockMutex(q->mutex);
return ret;
}
-static int decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
+static int decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_Condition *empty_queue_cond) {
memset(d, 0, sizeof(Decoder));
d->pkt = av_packet_alloc();
if (!d->pkt)
@@ -622,7 +624,7 @@ static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
do {
if (d->queue->nb_packets == 0)
- SDL_CondSignal(d->empty_queue_cond);
+ SDL_SignalCondition(d->empty_queue_cond);
if (d->packet_pending) {
d->packet_pending = 0;
} else {
@@ -693,7 +695,7 @@ static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
- if (!(f->cond = SDL_CreateCond())) {
+ if (!(f->cond = SDL_CreateCondition())) {
av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
@@ -715,13 +717,13 @@ static void frame_queue_destroy(FrameQueue *f)
av_frame_free(&vp->frame);
}
SDL_DestroyMutex(f->mutex);
- SDL_DestroyCond(f->cond);
+ SDL_DestroyCondition(f->cond);
}
static void frame_queue_signal(FrameQueue *f)
{
SDL_LockMutex(f->mutex);
- SDL_CondSignal(f->cond);
+ SDL_SignalCondition(f->cond);
SDL_UnlockMutex(f->mutex);
}
@@ -746,7 +748,7 @@ static Frame *frame_queue_peek_writable(FrameQueue *f)
SDL_LockMutex(f->mutex);
while (f->size >= f->max_size &&
!f->pktq->abort_request) {
- SDL_CondWait(f->cond, f->mutex);
+ SDL_WaitCondition(f->cond, f->mutex);
}
SDL_UnlockMutex(f->mutex);
@@ -762,7 +764,7 @@ static Frame *frame_queue_peek_readable(FrameQueue *f)
SDL_LockMutex(f->mutex);
while (f->size - f->rindex_shown <= 0 &&
!f->pktq->abort_request) {
- SDL_CondWait(f->cond, f->mutex);
+ SDL_WaitCondition(f->cond, f->mutex);
}
SDL_UnlockMutex(f->mutex);
@@ -778,7 +780,7 @@ static void frame_queue_push(FrameQueue *f)
f->windex = 0;
SDL_LockMutex(f->mutex);
f->size++;
- SDL_CondSignal(f->cond);
+ SDL_SignalCondition(f->cond);
SDL_UnlockMutex(f->mutex);
}
@@ -793,7 +795,7 @@ static void frame_queue_next(FrameQueue *f)
f->rindex = 0;
SDL_LockMutex(f->mutex);
f->size--;
- SDL_CondSignal(f->cond);
+ SDL_SignalCondition(f->cond);
SDL_UnlockMutex(f->mutex);
}
@@ -824,7 +826,7 @@ static void decoder_abort(Decoder *d, FrameQueue *fq)
static inline void fill_rectangle(int x, int y, int w, int h)
{
- SDL_Rect rect;
+ SDL_FRect rect;
rect.x = x;
rect.y = y;
rect.w = w;
@@ -835,19 +837,21 @@ static inline void fill_rectangle(int x, int y, int w, int h)
static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
{
- Uint32 format;
- int access, w, h;
- if (!*texture || SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
+ SDL_PropertiesID props = SDL_GetTextureProperties(*texture);
+ if (!*texture || !props ||
+ SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_WIDTH_NUMBER, 0) != new_width ||
+ SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0) != new_height ||
+ SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_FORMAT_NUMBER, 0) != new_format) {
void *pixels;
int pitch;
if (*texture)
SDL_DestroyTexture(*texture);
if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
return -1;
- if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
+ if (!SDL_SetTextureBlendMode(*texture, blendmode))
return -1;
if (init_texture) {
- if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
+ if (!SDL_LockTexture(*texture, NULL, &pixels, &pitch))
return -1;
memset(pixels, 0, pitch * new_height);
SDL_UnlockTexture(*texture);
@@ -857,7 +861,7 @@ static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_wid
return 0;
}
-static void calculate_display_rect(SDL_Rect *rect,
+static void calculate_display_rect(SDL_FRect *rect,
int scr_xleft, int scr_ytop, int scr_width, int scr_height,
int pic_width, int pic_height, AVRational pic_sar)
{
@@ -949,25 +953,14 @@ static enum AVAlphaMode sdl_supported_alpha_modes[] = {
static void set_sdl_yuv_conversion_mode(AVFrame *frame)
{
-#if SDL_VERSION_ATLEAST(2,0,8)
- SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
- if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
- if (frame->color_range == AVCOL_RANGE_JPEG)
- mode = SDL_YUV_CONVERSION_JPEG;
- else if (frame->colorspace == AVCOL_SPC_BT709)
- mode = SDL_YUV_CONVERSION_BT709;
- else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M)
- mode = SDL_YUV_CONVERSION_BT601;
- }
- SDL_SetYUVConversionMode(mode); /* FIXME: no support for linear transfer */
-#endif
+ /* TODO */
}
static void video_image_display(VideoState *is)
{
Frame *vp;
Frame *sp = NULL;
- SDL_Rect rect;
+ SDL_FRect rect;
vp = frame_queue_peek_last(&is->pictq);
if (vk_renderer) {
@@ -1032,11 +1025,11 @@ static void video_image_display(VideoState *is)
vp->flip_v = vp->frame->linesize[0] < 0;
}
- SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
+ SDL_RenderTextureRotated(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
set_sdl_yuv_conversion_mode(NULL);
if (sp) {
#if USE_ONEPASS_SUBTITLE_RENDER
- SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
+ SDL_RenderTexture(renderer, is->sub_texture, NULL, &rect);
#else
int i;
double xratio = (double)rect.w / (double)sp->width;
@@ -1047,7 +1040,7 @@ static void video_image_display(VideoState *is)
.y = rect.y + sub_rect->y * yratio,
.w = sub_rect->w * xratio,
.h = sub_rect->h * yratio};
- SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
+ SDL_RenderTexture(renderer, is->sub_texture, sub_rect, &target);
}
#endif
}
@@ -1202,7 +1195,7 @@ static void video_audio_display(VideoState *s)
}
SDL_UnlockTexture(s->vis_texture);
}
- SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
+ SDL_RenderTexture(renderer, s->vis_texture, NULL, NULL);
}
if (!s->paused)
s->xpos++;
@@ -1221,7 +1214,7 @@ static void stream_component_close(VideoState *is, int stream_index)
switch (codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
decoder_abort(&is->auddec, &is->sampq);
- SDL_CloseAudioDevice(audio_dev);
+ SDL_DestroyAudioStream(audio_stream);
decoder_destroy(&is->auddec);
swr_free(&is->swr_ctx);
av_freep(&is->audio_buf1);
@@ -1291,7 +1284,7 @@ static void stream_close(VideoState *is)
frame_queue_destroy(&is->pictq);
frame_queue_destroy(&is->sampq);
frame_queue_destroy(&is->subpq);
- SDL_DestroyCond(is->continue_read_thread);
+ SDL_DestroyCondition(is->continue_read_thread);
sws_freeContext(is->sub_convert_ctx);
av_free(is->filename);
if (is->vis_texture)
@@ -1337,7 +1330,7 @@ static void sigterm_handler(int sig)
static void set_default_window_size(int width, int height, AVRational sar)
{
- SDL_Rect rect;
+ SDL_FRect rect;
int max_width = screen_width ? screen_width : INT_MAX;
int max_height = screen_height ? screen_height : INT_MAX;
if (max_width == INT_MAX && max_height == INT_MAX)
@@ -1361,11 +1354,12 @@ static int video_open(VideoState *is)
SDL_SetWindowSize(window, w, h);
SDL_SetWindowPosition(window, screen_left, screen_top);
if (is_full_screen)
- SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+ SDL_SetWindowFullscreen(window, true);
SDL_ShowWindow(window);
is->width = w;
is->height = h;
+ is->shown = true;
return 0;
}
@@ -1373,7 +1367,7 @@ static int video_open(VideoState *is)
/* display the current picture, if any */
static void video_display(VideoState *is)
{
- if (!is->width)
+ if (!is->shown)
video_open(is);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
@@ -1492,7 +1486,7 @@ static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int by_bytes)
if (by_bytes)
is->seek_flags |= AVSEEK_FLAG_BYTE;
is->seek_req = 1;
- SDL_CondSignal(is->continue_read_thread);
+ SDL_SignalCondition(is->continue_read_thread);
}
}
@@ -1523,9 +1517,9 @@ static void toggle_mute(VideoState *is)
static void update_volume(VideoState *is, int sign, double step)
{
- double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
- int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
- is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
+ float volume_level = is->audio_volume ? (20 * log(is->audio_volume - 10)) : -1000.0;
+ float new_volume = pow(10.0, (volume_level + sign * step) / 20.0);
+ is->audio_volume = SDL_max(0.0, SDL_min(new_volume, 1.0));
}
static void step_to_next_frame(VideoState *is)
@@ -1876,9 +1870,9 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
if (!par)
return AVERROR(ENOMEM);
- for (i = 0; i < renderer_info.num_texture_formats; i++) {
+ for (i = 0; renderer_texture_formats[i] != SDL_PIXELFORMAT_UNKNOWN; i++) {
for (j = 0; j < FF_ARRAY_ELEMS(sdl_texture_format_map); j++) {
- if (renderer_info.texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
+ if (renderer_texture_formats[i] == sdl_texture_format_map[j].texture_fmt) {
pix_fmts[nb_pix_fmts++] = sdl_texture_format_map[j].format;
break;
}
@@ -2513,12 +2507,13 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
len1 = is->audio_buf_size - is->audio_buf_index;
if (len1 > len)
len1 = len;
- if (!is->muted && is->audio_buf && is->audio_volume == SDL_MIX_MAXVOLUME)
+ if (!is->muted && is->audio_buf && is->audio_volume == 1.0)
memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
else {
memset(stream, 0, len1);
if (!is->muted && is->audio_buf)
- SDL_MixAudioFormat(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, AUDIO_S16SYS, len1, is->audio_volume);
+ SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index,
+ SDL_AUDIO_S16, len1, is->audio_volume);
}
len -= len1;
stream += len1;
@@ -2532,9 +2527,22 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
}
}
+static void SDLCALL sdl3_audio_callback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount)
+{
+ if (additional_amount > 0) {
+ Uint8 *data = SDL_stack_alloc(Uint8, additional_amount);
+ if (data) {
+ /* TODO: inline and refactor */
+ sdl_audio_callback(userdata, data, additional_amount);
+ SDL_PutAudioStreamData(stream, data, additional_amount);
+ SDL_stack_free(data);
+ }
+ }
+}
+
static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int wanted_sample_rate, struct AudioParams *audio_hw_params)
{
- SDL_AudioSpec wanted_spec, spec;
+ SDL_AudioSpec wanted_spec;
const char *env;
static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
@@ -2560,12 +2568,8 @@ static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int
}
while (next_sample_rate_idx && next_sample_rates[next_sample_rate_idx] >= wanted_spec.freq)
next_sample_rate_idx--;
- wanted_spec.format = AUDIO_S16SYS;
- wanted_spec.silence = 0;
- wanted_spec.samples = FFMAX(SDL_AUDIO_MIN_BUFFER_SIZE, 2 << av_log2(wanted_spec.freq / SDL_AUDIO_MAX_CALLBACKS_PER_SEC));
- wanted_spec.callback = sdl_audio_callback;
- wanted_spec.userdata = opaque;
- while (!(audio_dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE))) {
+ wanted_spec.format = SDL_AUDIO_S16;
+ while (!(audio_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &wanted_spec, sdl3_audio_callback, opaque))) {
av_log(NULL, AV_LOG_WARNING, "SDL_OpenAudio (%d channels, %d Hz): %s\n",
wanted_spec.channels, wanted_spec.freq, SDL_GetError());
wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
@@ -2580,23 +2584,9 @@ static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int
}
av_channel_layout_default(wanted_channel_layout, wanted_spec.channels);
}
- if (spec.format != AUDIO_S16SYS) {
- av_log(NULL, AV_LOG_ERROR,
- "SDL advised audio format %d is not supported!\n", spec.format);
- return -1;
- }
- if (spec.channels != wanted_spec.channels) {
- av_channel_layout_uninit(wanted_channel_layout);
- av_channel_layout_default(wanted_channel_layout, spec.channels);
- if (wanted_channel_layout->order != AV_CHANNEL_ORDER_NATIVE) {
- av_log(NULL, AV_LOG_ERROR,
- "SDL advised channel count %d is not supported!\n", spec.channels);
- return -1;
- }
- }
audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
- audio_hw_params->freq = spec.freq;
+ audio_hw_params->freq = wanted_spec.freq;
if (av_channel_layout_copy(&audio_hw_params->ch_layout, wanted_channel_layout) < 0)
return -1;
audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->ch_layout.nb_channels, 1, audio_hw_params->fmt, 1);
@@ -2605,7 +2595,7 @@ static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
return -1;
}
- return spec.size;
+ return 0; /* TODO: is zero here ok? */
}
static int create_hwaccel(AVBufferRef **device_ctx)
@@ -2770,7 +2760,7 @@ static int stream_component_open(VideoState *is, int stream_index)
}
if ((ret = decoder_start(&is->auddec, audio_thread, "audio_decoder", is)) < 0)
goto out;
- SDL_PauseAudioDevice(audio_dev, 0);
+ SDL_ResumeAudioStreamDevice(audio_stream);
break;
case AVMEDIA_TYPE_VIDEO:
is->video_stream = stream_index;
@@ -2846,7 +2836,7 @@ static int read_thread(void *arg)
char metadata_description[96];
int pkt_in_play_range = 0;
const AVDictionaryEntry *t;
- SDL_mutex *wait_mutex = SDL_CreateMutex();
+ SDL_Mutex *wait_mutex = SDL_CreateMutex();
int scan_all_pmts_set = 0;
int64_t pkt_ts;
@@ -3096,7 +3086,7 @@ static int read_thread(void *arg)
stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) {
/* wait 10 ms */
SDL_LockMutex(wait_mutex);
- SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
+ SDL_WaitConditionTimeout(is->continue_read_thread, wait_mutex, 10);
SDL_UnlockMutex(wait_mutex);
continue;
}
@@ -3128,7 +3118,7 @@ static int read_thread(void *arg)
break;
}
SDL_LockMutex(wait_mutex);
- SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
+ SDL_WaitConditionTimeout(is->continue_read_thread, wait_mutex, 10);
SDL_UnlockMutex(wait_mutex);
continue;
} else {
@@ -3215,7 +3205,7 @@ static VideoState *stream_open(const char *filename,
packet_queue_init(&is->subtitleq) < 0)
goto fail;
- if (!(is->continue_read_thread = SDL_CreateCond())) {
+ if (!(is->continue_read_thread = SDL_CreateCondition())) {
av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
goto fail;
}
@@ -3229,8 +3219,7 @@ static VideoState *stream_open(const char *filename,
if (startup_volume > 100)
av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
startup_volume = av_clip(startup_volume, 0, 100);
- startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
- is->audio_volume = startup_volume;
+ is->audio_volume = startup_volume / 100.0;
is->muted = 0;
is->av_sync_type = av_sync_type;
is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
@@ -3325,7 +3314,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
static void toggle_full_screen(VideoState *is)
{
is_full_screen = !is_full_screen;
- SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
+ SDL_SetWindowFullscreen(window, is_full_screen);
}
static void toggle_audio_display(VideoState *is)
@@ -3343,9 +3332,9 @@ static void toggle_audio_display(VideoState *is)
static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
double remaining_time = 0.0;
SDL_PumpEvents();
- while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
+ while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST)) {
if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
- SDL_ShowCursor(0);
+ SDL_HideCursor();
cursor_hidden = 1;
}
if (remaining_time > 0.0)
@@ -3394,24 +3383,24 @@ static void event_loop(VideoState *cur_stream)
double x;
refresh_loop_wait_event(cur_stream, &event);
switch (event.type) {
- case SDL_KEYDOWN:
- if (exit_on_keydown || event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
+ case SDL_EVENT_KEY_DOWN:
+ if (exit_on_keydown || event.key.key == SDLK_ESCAPE || event.key.key == SDLK_Q) {
do_exit(cur_stream);
break;
}
// If we don't yet have a window, skip all key events, because read_thread might still be initializing...
if (!cur_stream->width)
continue;
- switch (event.key.keysym.sym) {
- case SDLK_f:
+ switch (event.key.key) {
+ case SDLK_F:
toggle_full_screen(cur_stream);
cur_stream->force_refresh = 1;
break;
- case SDLK_p:
+ case SDLK_P:
case SDLK_SPACE:
toggle_pause(cur_stream);
break;
- case SDLK_m:
+ case SDLK_M:
toggle_mute(cur_stream);
break;
case SDLK_KP_MULTIPLY:
@@ -3422,24 +3411,24 @@ static void event_loop(VideoState *cur_stream)
case SDLK_9:
update_volume(cur_stream, -1, SDL_VOLUME_STEP);
break;
- case SDLK_s: // S: Step to next frame
+ case SDLK_S: // S: Step to next frame
step_to_next_frame(cur_stream);
break;
- case SDLK_a:
+ case SDLK_A:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
break;
- case SDLK_v:
+ case SDLK_V:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
break;
- case SDLK_c:
+ case SDLK_C:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
break;
- case SDLK_t:
+ case SDLK_T:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
break;
- case SDLK_w:
+ case SDLK_W:
if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
if (++cur_stream->vfilter_idx >= nb_vfilters)
cur_stream->vfilter_idx = 0;
@@ -3502,7 +3491,7 @@ static void event_loop(VideoState *cur_stream)
break;
}
break;
- case SDL_MOUSEBUTTONDOWN:
+ case SDL_EVENT_MOUSE_BUTTON_DOWN:
if (exit_on_mousedown) {
do_exit(cur_stream);
break;
@@ -3517,13 +3506,13 @@ static void event_loop(VideoState *cur_stream)
last_mouse_left_click = av_gettime_relative();
}
}
- case SDL_MOUSEMOTION:
+ case SDL_EVENT_MOUSE_MOTION:
if (cursor_hidden) {
- SDL_ShowCursor(1);
+ SDL_ShowCursor();
cursor_hidden = 0;
}
cursor_last_shown = av_gettime_relative();
- if (event.type == SDL_MOUSEBUTTONDOWN) {
+ if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
if (event.button.button != SDL_BUTTON_RIGHT)
break;
x = event.button.x;
@@ -3557,22 +3546,19 @@ static void event_loop(VideoState *cur_stream)
stream_seek(cur_stream, ts, 0, 0);
}
break;
- case SDL_WINDOWEVENT:
- switch (event.window.event) {
- case SDL_WINDOWEVENT_SIZE_CHANGED:
- screen_width = cur_stream->width = event.window.data1;
- screen_height = cur_stream->height = event.window.data2;
- if (cur_stream->vis_texture) {
- SDL_DestroyTexture(cur_stream->vis_texture);
- cur_stream->vis_texture = NULL;
- }
- if (vk_renderer)
- vk_renderer_resize(vk_renderer, screen_width, screen_height);
- case SDL_WINDOWEVENT_EXPOSED:
- cur_stream->force_refresh = 1;
+ case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
+ screen_width = cur_stream->width = event.window.data1;
+ screen_height = cur_stream->height = event.window.data2;
+ if (cur_stream->vis_texture) {
+ SDL_DestroyTexture(cur_stream->vis_texture);
+ cur_stream->vis_texture = NULL;
}
+ if (vk_renderer)
+ vk_renderer_resize(vk_renderer, screen_width, screen_height);
+ case SDL_EVENT_WINDOW_EXPOSED:
+ cur_stream->force_refresh = 1;
break;
- case SDL_QUIT:
+ case SDL_EVENT_QUIT:
case FF_QUIT_EVENT:
do_exit(cur_stream);
break;
@@ -3820,25 +3806,24 @@ int main(int argc, char **argv)
if (display_disable) {
video_disable = 1;
}
- flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
+ flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO;
if (audio_disable)
flags &= ~SDL_INIT_AUDIO;
else {
/* Try to work around an occasional ALSA buffer underflow issue when the
* period size is NPOT due to ALSA resampling by forcing the buffer size. */
if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
- SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
+ SDL_setenv_unsafe("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
}
if (display_disable)
flags &= ~SDL_INIT_VIDEO;
- if (SDL_Init (flags)) {
+ if (!SDL_Init (flags)) {
av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
exit(1);
}
- SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
- SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
+ SDL_SetEventEnabled(SDL_EVENT_USER, false);
if (!display_disable) {
int flags = SDL_WINDOW_HIDDEN;
@@ -3871,8 +3856,7 @@ int main(int argc, char **argv)
enable_vulkan = 0;
}
}
- window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+ window = SDL_CreateWindow(program_name, default_width, default_height, flags);
if (!window) {
av_log(NULL, AV_LOG_FATAL, "Failed to create window: %s", SDL_GetError());
do_exit(NULL);
@@ -3895,19 +3879,24 @@ int main(int argc, char **argv)
do_exit(NULL);
}
} else {
- renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1");
+ renderer = SDL_CreateRenderer(window, NULL);
if (!renderer) {
- av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
- renderer = SDL_CreateRenderer(window, -1, 0);
+ av_log(NULL, AV_LOG_FATAL, "Failed to create renderer: %s", SDL_GetError());
+ do_exit(NULL);
}
- if (renderer) {
- if (!SDL_GetRendererInfo(renderer, &renderer_info))
- av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
+ if (!strcmp(SDL_GetRendererName(renderer), SDL_SOFTWARE_RENDERER)) {
+ av_log(NULL, AV_LOG_WARNING, "Created renderer is not hardware accelerated\n");
}
- if (!renderer || !renderer_info.num_texture_formats) {
- av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
+ SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
+ renderer_texture_formats = SDL_GetPointerProperty(props, SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER, NULL);
+ if (!renderer_texture_formats ||
+ *renderer_texture_formats == SDL_PIXELFORMAT_UNKNOWN) {
+ av_log(NULL, AV_LOG_FATAL, "Created renderer supports no texture formats");
do_exit(NULL);
}
+
+ av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n",SDL_GetRendererName(renderer));
}
}
diff --git a/fftools/ffplay_renderer.c b/fftools/ffplay_renderer.c
index 1321452ad8..83f8849e44 100644
--- a/fftools/ffplay_renderer.c
+++ b/fftools/ffplay_renderer.c
@@ -220,7 +220,7 @@ static int create_vk_by_hwcontext(VkRenderer *renderer,
// There is no way to pass SDL GetInstanceProcAddr to hwdevice.
// Check the result and return error if they don't match.
- if (hwctx->get_proc_addr != SDL_Vulkan_GetVkGetInstanceProcAddr()) {
+ if (hwctx->get_proc_addr != (PFN_vkGetInstanceProcAddr) SDL_Vulkan_GetVkGetInstanceProcAddr()) {
av_log(renderer, AV_LOG_ERROR,
"hwdevice and SDL use different get_proc_addr. "
"Try -vulkan_params create_by_placebo=1\n");
@@ -347,7 +347,7 @@ static int create_vk_by_placebo(VkRenderer *renderer,
const char **dev_exts;
int num_dev_exts;
- ctx->get_proc_addr = SDL_Vulkan_GetVkGetInstanceProcAddr();
+ ctx->get_proc_addr = (PFN_vkGetInstanceProcAddr) SDL_Vulkan_GetVkGetInstanceProcAddr();
ctx->placebo_instance = pl_vk_inst_create(ctx->vk_log, pl_vk_inst_params(
.get_proc_addr = ctx->get_proc_addr,
@@ -459,7 +459,7 @@ static int create(VkRenderer *renderer, SDL_Window *window, AVDictionary *opt)
ctx->vk_log = pl_log_create(PL_API_VER, &vk_log_params);
- if (!SDL_Vulkan_GetInstanceExtensions(window, &num_ext, NULL)) {
+ if (!SDL_Vulkan_GetInstanceExtensions(&num_ext, NULL)) {
av_log(NULL, AV_LOG_FATAL, "Failed to get vulkan extensions: %s\n",
SDL_GetError());
return AVERROR_EXTERNAL;
@@ -471,7 +471,7 @@ static int create(VkRenderer *renderer, SDL_Window *window, AVDictionary *opt)
goto out;
}
- SDL_Vulkan_GetInstanceExtensions(window, &num_ext, ext);
+ SDL_Vulkan_GetInstanceExtensions(&num_ext, ext);
entry = av_dict_get(opt, "create_by_placebo", NULL, 0);
if (entry && strtol(entry->value, NULL, 10))
@@ -481,7 +481,7 @@ static int create(VkRenderer *renderer, SDL_Window *window, AVDictionary *opt)
if (ret < 0)
goto out;
- if (!SDL_Vulkan_CreateSurface(window, ctx->inst, &ctx->vk_surface)) {
+ if (!SDL_Vulkan_CreateSurface(window, ctx->inst, NULL, &ctx->vk_surface)) {
ret = AVERROR_EXTERNAL;
goto out;
}
@@ -496,7 +496,7 @@ static int create(VkRenderer *renderer, SDL_Window *window, AVDictionary *opt)
goto out;
}
- SDL_Vulkan_GetDrawableSize(window, &w, &h);
+ SDL_GetWindowSizeInPixels(window, &w, &h);
pl_swapchain_resize(ctx->swapchain, &w, &h);
ctx->renderer = pl_renderer_create(ctx->vk_log, ctx->placebo_vulkan->gpu);
diff --git a/fftools/ffplay_renderer.h b/fftools/ffplay_renderer.h
index dd8e9c06e7..f026f42692 100644
--- a/fftools/ffplay_renderer.h
+++ b/fftools/ffplay_renderer.h
@@ -19,7 +19,7 @@
#ifndef FFTOOLS_FFPLAY_RENDERER_H
#define FFTOOLS_FFPLAY_RENDERER_H
-#include <SDL.h>
+#include <SDL3/SDL.h>
#include "libavutil/frame.h"
--
2.51.2
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-02 22:41 [FFmpeg-devel] [PATCH] fftools/ffplay: migrate to SDL3 Marcin Serwin via ffmpeg-devel
@ 2026-01-03 4:41 ` Michael Niedermayer via ffmpeg-devel
2026-01-03 8:46 ` Marcin Serwin via ffmpeg-devel
2026-01-03 4:50 ` Gyan Doshi via ffmpeg-devel
2026-01-03 5:40 ` Zhao Zhili via ffmpeg-devel
2 siblings, 1 reply; 17+ messages in thread
From: Michael Niedermayer via ffmpeg-devel @ 2026-01-03 4:41 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Michael Niedermayer
[-- Attachment #1.1: Type: text/plain, Size: 1030 bytes --]
Hi Marcin
On Fri, Jan 02, 2026 at 11:41:01PM +0100, Marcin Serwin via ffmpeg-devel wrote:
> Migrates the FFplay media player to the new SDL version using the
> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>
> Signed-off-by: Marcin Serwin <marcin@serwin.dev>
> ---
> This is just first iteration but I wanted to make sure if you're interested in
> doing the migration and gather some early feedback. With this path I am able to
> play some basic video and audio files on my Linux system but I haven't tested it
> with other platforms.
As this removes SDL2 support, which current linux distributions support SDL3 ?
IIUC ubuntu 24.04 LTS does not support SDL3 so this patch would remove ffplay
support
thx
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Concerning the gods, I have no means of knowing whether they exist or not
or of what sort they may be, because of the obscurity of the subject, and
the brevity of human life -- Protagoras
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 163 bytes --]
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-02 22:41 [FFmpeg-devel] [PATCH] fftools/ffplay: migrate to SDL3 Marcin Serwin via ffmpeg-devel
2026-01-03 4:41 ` [FFmpeg-devel] " Michael Niedermayer via ffmpeg-devel
@ 2026-01-03 4:50 ` Gyan Doshi via ffmpeg-devel
2026-01-03 8:48 ` Marcin Serwin via ffmpeg-devel
2026-01-03 13:13 ` Nicolas George via ffmpeg-devel
2026-01-03 5:40 ` Zhao Zhili via ffmpeg-devel
2 siblings, 2 replies; 17+ messages in thread
From: Gyan Doshi via ffmpeg-devel @ 2026-01-03 4:50 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Gyan Doshi
On 2026-01-03 04:11 am, Marcin Serwin via ffmpeg-devel wrote:
> Migrates the FFplay media player to the new SDL version using the
> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>
> Signed-off-by: Marcin Serwin <marcin@serwin.dev>
> ---
> This is just first iteration but I wanted to make sure if you're interested in
> doing the migration and gather some early feedback. With this path I am able to
> play some basic video and audio files on my Linux system but I haven't tested it
> with other platforms.
Patches should be sent as PRs at https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls
You're dropping support for SDL2. Is SDL3 not backward compatible?
Regards,
Gyan
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-02 22:41 [FFmpeg-devel] [PATCH] fftools/ffplay: migrate to SDL3 Marcin Serwin via ffmpeg-devel
2026-01-03 4:41 ` [FFmpeg-devel] " Michael Niedermayer via ffmpeg-devel
2026-01-03 4:50 ` Gyan Doshi via ffmpeg-devel
@ 2026-01-03 5:40 ` Zhao Zhili via ffmpeg-devel
2026-01-03 7:12 ` Gyan Doshi via ffmpeg-devel
2 siblings, 1 reply; 17+ messages in thread
From: Zhao Zhili via ffmpeg-devel @ 2026-01-03 5:40 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Marcin Serwin, Zhao Zhili
> On Jan 3, 2026, at 06:41, Marcin Serwin via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
>
> Migrates the FFplay media player to the new SDL version using the
> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>
> Signed-off-by: Marcin Serwin <marcin@serwin.dev>
> ---
> This is just first iteration but I wanted to make sure if you're interested in
> doing the migration and gather some early feedback. With this path I am able to
> play some basic video and audio files on my Linux system but I haven't tested it
> with other platforms.
I've also considered the issue of supporting SDL3. The challenge is
how to maintain support for both SDL2 and SDL3 while avoiding a
codebase cluttered with conditional compilation, which would be
difficult to maintain.
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 5:40 ` Zhao Zhili via ffmpeg-devel
@ 2026-01-03 7:12 ` Gyan Doshi via ffmpeg-devel
2026-01-03 8:59 ` Marcin Serwin via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Gyan Doshi via ffmpeg-devel @ 2026-01-03 7:12 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Gyan Doshi
On 2026-01-03 11:10 am, Zhao Zhili via ffmpeg-devel wrote:
>
>> On Jan 3, 2026, at 06:41, Marcin Serwin via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
>>
>> Migrates the FFplay media player to the new SDL version using the
>> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>>
> I've also considered the issue of supporting SDL3. The challenge is
> how to maintain support for both SDL2 and SDL3 while avoiding a
> codebase cluttered with conditional compilation, which would be
> difficult to maintain.
Support for SDL1 was dropped on the same day as SDL2 support was added.
What are the relevant improvements in SDL3 as far as current ffplay.c is
concerned?
Regards,
Gyan
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 4:41 ` [FFmpeg-devel] " Michael Niedermayer via ffmpeg-devel
@ 2026-01-03 8:46 ` Marcin Serwin via ffmpeg-devel
0 siblings, 0 replies; 17+ messages in thread
From: Marcin Serwin via ffmpeg-devel @ 2026-01-03 8:46 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Cc: Michael Niedermayer, Marcin Serwin
[-- Attachment #1.1: Type: text/plain, Size: 813 bytes --]
On Sat Jan 3, 2026 at 5:41 AM CET, Michael Niedermayer via ffmpeg-devel wrote:
> On Fri, Jan 02, 2026 at 11:41:01PM +0100, Marcin Serwin via ffmpeg-devel wrote:
>> Migrates the FFplay media player to the new SDL version using the
>> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>
> As this removes SDL2 support, which current linux distributions support SDL3 ?
> IIUC ubuntu 24.04 LTS does not support SDL3 so this patch would remove ffplay
> support
You're right, Ubuntu only packages it since 25.04 so perhaps it's too early to
drop the SDL2 support. As for other major distros it's currently available in
Debian >= 13, Fedora >= 40, Alpine Linux >= 3.22, Arch, and Gentoo.
Is there a list of distributions that ffmpeg aims to support?
--
Best regards,
Marcin Serwin
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
[-- Attachment #2: Type: text/plain, Size: 163 bytes --]
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 4:50 ` Gyan Doshi via ffmpeg-devel
@ 2026-01-03 8:48 ` Marcin Serwin via ffmpeg-devel
2026-01-03 13:13 ` Nicolas George via ffmpeg-devel
1 sibling, 0 replies; 17+ messages in thread
From: Marcin Serwin via ffmpeg-devel @ 2026-01-03 8:48 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Gyan Doshi, Marcin Serwin
[-- Attachment #1.1: Type: text/plain, Size: 700 bytes --]
On Sat Jan 3, 2026 at 5:50 AM CET, Gyan Doshi via ffmpeg-devel wrote:
> On 2026-01-03 04:11 am, Marcin Serwin via ffmpeg-devel wrote:
>> Migrates the FFplay media player to the new SDL version using the
>> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>
> Patches should be sent as PRs at https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls
I was following https://www.ffmpeg.org/developer.html#Submitting-patches-1,
should it be updated? Should I resubmit the patch as a PR?
> You're dropping support for SDL2. Is SDL3 not backward compatible?
No, it's not. Perhaps you're thinking about sdl2-compat which is a compatibility
layer.
--
Best regards,
Marcin Serwin
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
[-- Attachment #2: Type: text/plain, Size: 163 bytes --]
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 7:12 ` Gyan Doshi via ffmpeg-devel
@ 2026-01-03 8:59 ` Marcin Serwin via ffmpeg-devel
2026-01-03 12:59 ` Zhao Zhili via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Marcin Serwin via ffmpeg-devel @ 2026-01-03 8:59 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Gyan Doshi, Marcin Serwin
[-- Attachment #1.1: Type: text/plain, Size: 1279 bytes --]
On Sat Jan 3, 2026 at 8:12 AM CET, Gyan Doshi via ffmpeg-devel wrote:
>>> Migrates the FFplay media player to the new SDL version using the
>>> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>>>
>> I've also considered the issue of supporting SDL3. The challenge is
>> how to maintain support for both SDL2 and SDL3 while avoiding a
>> codebase cluttered with conditional compilation, which would be
>> difficult to maintain.
>
> Support for SDL1 was dropped on the same day as SDL2 support was added.
Most of the changes are renames so perhaps it could be possible to make
a localized block with `#define`s to minimize the number of conditional
compilation macros throughout the logic. That being said I hoped for doing it
the same way as SDL 1->2 migration.
> What are the relevant improvements in SDL3 as far as current ffplay.c is
> concerned?
This is mostly code hygiene as SDL3 has cleaner and more consistent API. I'm not
aware of any functional changes between it and just using sdl2-compat.
One possible future improvement is utilizing the new GPU API to simplify the
Vulkan renderer code. Or perhaps it can be removed entirely in favor of setting
SDL_HINT_RENDER_DRIVER to "vulkan".
--
Best regards,
Marcin Serwin
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
[-- Attachment #2: Type: text/plain, Size: 163 bytes --]
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 8:59 ` Marcin Serwin via ffmpeg-devel
@ 2026-01-03 12:59 ` Zhao Zhili via ffmpeg-devel
2026-01-03 13:12 ` Nicolas George via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Zhao Zhili via ffmpeg-devel @ 2026-01-03 12:59 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Marcin Serwin, Zhao Zhili
> On Jan 3, 2026, at 16:59, Marcin Serwin via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
>
> On Sat Jan 3, 2026 at 8:12 AM CET, Gyan Doshi via ffmpeg-devel wrote:
>>>> Migrates the FFplay media player to the new SDL version using the
>>>> official tutorial at https://wiki.libsdl.org/SDL3/README-migration.
>>>>
>>> I've also considered the issue of supporting SDL3. The challenge is
>>> how to maintain support for both SDL2 and SDL3 while avoiding a
>>> codebase cluttered with conditional compilation, which would be
>>> difficult to maintain.
>>
>> Support for SDL1 was dropped on the same day as SDL2 support was added.
>
> Most of the changes are renames so perhaps it could be possible to make
> a localized block with `#define`s to minimize the number of conditional
> compilation macros throughout the logic. That being said I hoped for doing it
> the same way as SDL 1->2 migration.
>
>> What are the relevant improvements in SDL3 as far as current ffplay.c is
>> concerned?
>
> This is mostly code hygiene as SDL3 has cleaner and more consistent API. I'm not
> aware of any functional changes between it and just using sdl2-compat.
>
> One possible future improvement is utilizing the new GPU API to simplify the
> Vulkan renderer code. Or perhaps it can be removed entirely in favor of setting
> SDL_HINT_RENDER_DRIVER to "vulkan".
The ffplay vulkan renderer is focus on hardware decoding interoperation and better
colorspace support. I don't think SDL3 can replace it directly.
>
> --
> Best regards,
> Marcin Serwin
> _______________________________________________
> ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
> To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 12:59 ` Zhao Zhili via ffmpeg-devel
@ 2026-01-03 13:12 ` Nicolas George via ffmpeg-devel
2026-01-03 15:14 ` Zhao Zhili via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Nicolas George via ffmpeg-devel @ 2026-01-03 13:12 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George
Zhao Zhili via ffmpeg-devel (HE12026-01-03):
> The ffplay vulkan renderer is focus on hardware decoding interoperation and better
> colorspace support. I don't think SDL3 can replace it directly.
Both should be in libavdevice, and ffplay should be using libavdevice
for its video and audio output.
Regards,
--
Nicolas George
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 4:50 ` Gyan Doshi via ffmpeg-devel
2026-01-03 8:48 ` Marcin Serwin via ffmpeg-devel
@ 2026-01-03 13:13 ` Nicolas George via ffmpeg-devel
2026-01-03 13:59 ` Neal Gompa via ffmpeg-devel
1 sibling, 1 reply; 17+ messages in thread
From: Nicolas George via ffmpeg-devel @ 2026-01-03 13:13 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George
Gyan Doshi via ffmpeg-devel (HE12026-01-03):
> Patches should be sent as PRs at https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls
That would have mean a lot fewer people and interesting remarks in the
discussion.
This forge shit is weakening the communication in the project.
Regards,
--
Nicolas George
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 13:13 ` Nicolas George via ffmpeg-devel
@ 2026-01-03 13:59 ` Neal Gompa via ffmpeg-devel
2026-01-03 14:29 ` Nicolas George via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Neal Gompa via ffmpeg-devel @ 2026-01-03 13:59 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George, Neal Gompa
On Sat, Jan 3, 2026 at 8:13 AM Nicolas George via ffmpeg-devel
<ffmpeg-devel@ffmpeg.org> wrote:
>
> Gyan Doshi via ffmpeg-devel (HE12026-01-03):
> > Patches should be sent as PRs at https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls
>
> That would have mean a lot fewer people and interesting remarks in the
> discussion.
>
> This forge shit is weakening the communication in the project.
>
Honestly, no. It's far easier to track and review on the forge than it
is in here. I personally would prefer to provide feedback there and be
able to subscribe to that pull request to track updates.
This mailing list should be for *discussion* and not patches (and yes
I know what the description of this ML says, that's not the point).
The email patch review model is really hard to track and I find it
frustrating in general.
--
真実はいつも一つ!/ Always, there's only one truth!
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 13:59 ` Neal Gompa via ffmpeg-devel
@ 2026-01-03 14:29 ` Nicolas George via ffmpeg-devel
0 siblings, 0 replies; 17+ messages in thread
From: Nicolas George via ffmpeg-devel @ 2026-01-03 14:29 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George
Neal Gompa via ffmpeg-devel (HE12026-01-03):
> Honestly, no. It's far easier to track and review on the forge than it
> is in here. I personally would prefer to provide feedback there and be
> able to subscribe to that pull request to track updates.
You can say that only if you would subscribe to only a handful of pull
requests. I am talking about the people who know about the project as a
whole.
> This mailing list should be for *discussion* and not patches
Reviewing patches is discussion.
> The email patch review model is really hard to track and I find it
> frustrating in general.
I suggest you learn to use a good mail client. The story goes:
luser mail client < forge << advanced mail client
Regards,
--
Nicolas George
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 13:12 ` Nicolas George via ffmpeg-devel
@ 2026-01-03 15:14 ` Zhao Zhili via ffmpeg-devel
2026-01-03 15:16 ` Nicolas George via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Zhao Zhili via ffmpeg-devel @ 2026-01-03 15:14 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George, Zhao Zhili
> On Jan 3, 2026, at 21:12, Nicolas George via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
>
> Zhao Zhili via ffmpeg-devel (HE12026-01-03):
>> The ffplay vulkan renderer is focus on hardware decoding interoperation and better
>> colorspace support. I don't think SDL3 can replace it directly.
>
> Both should be in libavdevice, and ffplay should be using libavdevice
> for its video and audio output.
How avdevice supposed to work with hardware AVFrame?
>
> Regards,
>
> --
> Nicolas George
> _______________________________________________
> ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
> To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 15:14 ` Zhao Zhili via ffmpeg-devel
@ 2026-01-03 15:16 ` Nicolas George via ffmpeg-devel
2026-01-03 15:39 ` Zhao Zhili via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Nicolas George via ffmpeg-devel @ 2026-01-03 15:16 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George
Zhao Zhili via ffmpeg-devel (HE12026-01-03):
> How avdevice supposed to work with hardware AVFrame?
The same way ffplay currently works.
Regards,
--
Nicolas George
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 15:16 ` Nicolas George via ffmpeg-devel
@ 2026-01-03 15:39 ` Zhao Zhili via ffmpeg-devel
2026-01-03 15:50 ` Nicolas George via ffmpeg-devel
0 siblings, 1 reply; 17+ messages in thread
From: Zhao Zhili via ffmpeg-devel @ 2026-01-03 15:39 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George, Zhao Zhili
> On Jan 3, 2026, at 23:16, Nicolas George via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
>
> Zhao Zhili via ffmpeg-devel (HE12026-01-03):
>> How avdevice supposed to work with hardware AVFrame?
>
> The same way ffplay currently works.
ffplay renderer works directly with AVFrame, while avdeivce works with AVPacket
and AVFrame wrapped in AVPacket.
I guess for similar reasons that gfxcapture is implemented as a filter source than a
input device, to avoid the AVFrame to AVPacket conversation.
> Regards,
>
> --
> Nicolas George
> _______________________________________________
> ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
> To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] Re: [PATCH] fftools/ffplay: migrate to SDL3
2026-01-03 15:39 ` Zhao Zhili via ffmpeg-devel
@ 2026-01-03 15:50 ` Nicolas George via ffmpeg-devel
0 siblings, 0 replies; 17+ messages in thread
From: Nicolas George via ffmpeg-devel @ 2026-01-03 15:50 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Nicolas George
Zhao Zhili via ffmpeg-devel (HE12026-01-03):
> ffplay renderer works directly with AVFrame,
Sure, but:
> while avdeivce works with AVPacket
> and AVFrame wrapped in AVPacket.
… so it is not an issue, is it?
> I guess for similar reasons that gfxcapture is implemented as a filter source than a
> input device, to avoid the AVFrame to AVPacket conversation.
My guess is that the author just did it like that for no specific
reason.
Regards,
--
Nicolas George
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-01-03 15:50 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-02 22:41 [FFmpeg-devel] [PATCH] fftools/ffplay: migrate to SDL3 Marcin Serwin via ffmpeg-devel
2026-01-03 4:41 ` [FFmpeg-devel] " Michael Niedermayer via ffmpeg-devel
2026-01-03 8:46 ` Marcin Serwin via ffmpeg-devel
2026-01-03 4:50 ` Gyan Doshi via ffmpeg-devel
2026-01-03 8:48 ` Marcin Serwin via ffmpeg-devel
2026-01-03 13:13 ` Nicolas George via ffmpeg-devel
2026-01-03 13:59 ` Neal Gompa via ffmpeg-devel
2026-01-03 14:29 ` Nicolas George via ffmpeg-devel
2026-01-03 5:40 ` Zhao Zhili via ffmpeg-devel
2026-01-03 7:12 ` Gyan Doshi via ffmpeg-devel
2026-01-03 8:59 ` Marcin Serwin via ffmpeg-devel
2026-01-03 12:59 ` Zhao Zhili via ffmpeg-devel
2026-01-03 13:12 ` Nicolas George via ffmpeg-devel
2026-01-03 15:14 ` Zhao Zhili via ffmpeg-devel
2026-01-03 15:16 ` Nicolas George via ffmpeg-devel
2026-01-03 15:39 ` Zhao Zhili via ffmpeg-devel
2026-01-03 15:50 ` Nicolas George via ffmpeg-devel
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