This introduces a new alternative FFmpeg-based implementation for the MF byte stream handlers, while keeping the current GStreamer-based as default.
The new implementation can be enabled by setting the DWORD value:
DisableGstByteStreamHandler = 1
in the HKCU\Software\Wine\MediaFoundation registry key.
From: Rémi Bernon rbernon@codeweavers.com
--- configure.ac | 1 + dlls/winedmo/Makefile.in | 4 ++++ dlls/winedmo/main.c | 33 +++++++++++++++++++++++++++++++++ dlls/winedmo/winedmo.spec | 1 + 4 files changed, 39 insertions(+) create mode 100644 dlls/winedmo/Makefile.in create mode 100644 dlls/winedmo/main.c create mode 100644 dlls/winedmo/winedmo.spec
diff --git a/configure.ac b/configure.ac index 4dcb780013a..8b44370122f 100644 --- a/configure.ac +++ b/configure.ac @@ -3290,6 +3290,7 @@ WINE_CONFIG_MAKEFILE(dlls/winebus.sys) WINE_CONFIG_MAKEFILE(dlls/winecoreaudio.drv) WINE_CONFIG_MAKEFILE(dlls/winecrt0) WINE_CONFIG_MAKEFILE(dlls/wined3d) +WINE_CONFIG_MAKEFILE(dlls/winedmo) WINE_CONFIG_MAKEFILE(dlls/winegstreamer) WINE_CONFIG_MAKEFILE(dlls/winehid.sys) WINE_CONFIG_MAKEFILE(dlls/winemac.drv) diff --git a/dlls/winedmo/Makefile.in b/dlls/winedmo/Makefile.in new file mode 100644 index 00000000000..e73a82235c6 --- /dev/null +++ b/dlls/winedmo/Makefile.in @@ -0,0 +1,4 @@ +MODULE = winedmo.dll + +SOURCES = \ + main.c diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c new file mode 100644 index 00000000000..2d86fe05fd0 --- /dev/null +++ b/dlls/winedmo/main.c @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Rémi Bernon for CodeWeavers + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stddef.h> +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dmo); + +BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) +{ + TRACE( "instance %p, reason %lu, reserved %p\n", instance, reason, reserved ); + return TRUE; +} diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec new file mode 100644 index 00000000000..76421d7e35b --- /dev/null +++ b/dlls/winedmo/winedmo.spec @@ -0,0 +1 @@ +# nothing to export
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winedmo/Makefile.in | 4 ++- dlls/winedmo/main.c | 12 ++++++++ dlls/winedmo/unix_private.h | 29 +++++++++++++++++++ dlls/winedmo/unixlib.c | 55 +++++++++++++++++++++++++++++++++++++ dlls/winedmo/unixlib.h | 38 +++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 dlls/winedmo/unix_private.h create mode 100644 dlls/winedmo/unixlib.c create mode 100644 dlls/winedmo/unixlib.h
diff --git a/dlls/winedmo/Makefile.in b/dlls/winedmo/Makefile.in index e73a82235c6..bea3b43546a 100644 --- a/dlls/winedmo/Makefile.in +++ b/dlls/winedmo/Makefile.in @@ -1,4 +1,6 @@ MODULE = winedmo.dll +UNIXLIB = winedmo.so
SOURCES = \ - main.c + main.c \ + unixlib.c diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 2d86fe05fd0..1e6c074b068 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -23,11 +23,23 @@ #include "winbase.h"
#include "wine/debug.h" +#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmo);
BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) { TRACE( "instance %p, reason %lu, reserved %p\n", instance, reason, reserved ); + + if (reason == DLL_PROCESS_ATTACH) + { + NTSTATUS status; + DisableThreadLibraryCalls( instance ); + + status = __wine_init_unix_call(); + if (!status) status = UNIX_CALL( process_attach, NULL ); + if (status) WARN( "Failed to init unixlib, status %#lx\n", status ); + } + return TRUE; } diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h new file mode 100644 index 00000000000..a34021d7339 --- /dev/null +++ b/dlls/winedmo/unix_private.h @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Rémi Bernon for CodeWeavers + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include <stddef.h> +#include <stdarg.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" + +#include "unixlib.h" diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c new file mode 100644 index 00000000000..7d27e031e37 --- /dev/null +++ b/dlls/winedmo/unixlib.c @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Rémi Bernon for CodeWeavers + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include "unix_private.h" + +#include "wine/debug.h" + +#define MAKE_UNSUPPORTED_ENTRY( name ) \ + static NTSTATUS name( void *arg ) \ + { \ + return STATUS_NOT_SUPPORTED; \ + } +MAKE_UNSUPPORTED_ENTRY( process_attach ) +#undef MAKE_UNSUPPORTED_ENTRY + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ +#define X( name ) [unix_##name] = name + X( process_attach ), +}; + +C_ASSERT(ARRAY_SIZE(__wine_unix_call_funcs) == unix_funcs_count); + +#ifdef _WIN64 + +const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ +#define X64( name ) [unix_##name] = wow64_##name + X( process_attach ), +}; + +C_ASSERT(ARRAY_SIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count); + +#endif /* _WIN64 */ diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h new file mode 100644 index 00000000000..c1b0542f33b --- /dev/null +++ b/dlls/winedmo/unixlib.h @@ -0,0 +1,38 @@ +/* + * Copyright 2024 Rémi Bernon for CodeWeavers + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINEDMO_UNIXLIB_H +#define __WINE_WINEDMO_UNIXLIB_H + +#include <stddef.h> +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" + +#include "wine/unixlib.h" + +enum unix_funcs +{ + unix_process_attach, + unix_funcs_count, +}; + +#define UNIX_CALL( func, params ) WINE_UNIX_CALL( unix_##func, params ) + +#endif /* __WINE_WINEDMO_UNIXLIB_H */
From: Rémi Bernon rbernon@codeweavers.com
--- configure.ac | 16 +++++++++++++++ dlls/winedmo/Makefile.in | 2 ++ dlls/winedmo/unix_private.h | 6 ++++++ dlls/winedmo/unixlib.c | 39 +++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+)
diff --git a/configure.ac b/configure.ac index 8b44370122f..01949a711ab 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,7 @@ AC_ARG_WITH(capi, AS_HELP_STRING([--without-capi],[do not use CAPI (ISDN su AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the CoreAudio sound support])) AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS])) AC_ARG_WITH(dbus, AS_HELP_STRING([--without-dbus],[do not use DBus (dynamic device support)])) +AC_ARG_WITH(ffmpeg, AS_HELP_STRING([--without-ffmpeg],[do not use the FFmpeg library])) AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig])) AC_ARG_WITH(freetype, AS_HELP_STRING([--without-freetype],[do not use the FreeType library])) AC_ARG_WITH(gettext, AS_HELP_STRING([--without-gettext],[do not use gettext])) @@ -1630,6 +1631,21 @@ WINE_NOTICE_WITH(pulse, [test -z "$PULSE_LIBS"], [libpulse ${notice_platform}development files not found or too old, Pulse won't be supported.], [enable_winepulse_drv])
+dnl **** Check for FFmpeg **** +if test "x$with_ffmpeg" != "xno"; +then + WINE_PACKAGE_FLAGS(FFMPEG,[libavutil],,,, + [AC_CHECK_HEADER([libavutil/avutil.h], + [AC_CHECK_LIB(avutil,av_log_set_callback,[:],[FFMPEG_LIBS=""],[$FFMPEG_LIBS])], + [FFMPEG_LIBS=""])]) + if test "x$FFMPEG_LIBS" != "x"; + then + FFMPEG_CFLAGS="-DENABLE_FFMPEG $FFMPEG_CFLAGS" + fi +fi +WINE_NOTICE_WITH(ffmpeg,[test -z "x$FFMPEG_LIBS"], + [FFmpeg ${notice_platform}development files not found.]) + dnl **** Check for gstreamer **** if test "x$with_gstreamer" != "xno" then diff --git a/dlls/winedmo/Makefile.in b/dlls/winedmo/Makefile.in index bea3b43546a..939941884e8 100644 --- a/dlls/winedmo/Makefile.in +++ b/dlls/winedmo/Makefile.in @@ -1,5 +1,7 @@ MODULE = winedmo.dll UNIXLIB = winedmo.so +UNIX_CFLAGS = $(FFMPEG_CFLAGS) +UNIX_LIBS = $(FFMPEG_LIBS) $(PTHREAD_LIBS)
SOURCES = \ main.c \ diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index a34021d7339..8e97cede3f8 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -27,3 +27,9 @@ #include "winbase.h"
#include "unixlib.h" + +#ifdef ENABLE_FFMPEG + +#include <libavutil/avutil.h> + +#endif /* ENABLE_FFMPEG */ diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 7d27e031e37..83fc8e01e91 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -26,14 +26,53 @@
#include "wine/debug.h"
+WINE_DEFAULT_DEBUG_CHANNEL(dmo); + +#ifdef ENABLE_FFMPEG + +static void vlog( void *ctx, int level, const char *fmt, va_list va_args ) +{ + enum __wine_debug_class dbcl = __WINE_DBCL_TRACE; + + /* FFmpeg may spawn and log from internal non-Wine threads */ + if (!NtCurrentTeb()) + { + vfprintf( stderr, fmt, va_args ); + return; + } + + if (level <= AV_LOG_ERROR) dbcl = __WINE_DBCL_ERR; + if (level <= AV_LOG_WARNING) dbcl = __WINE_DBCL_WARN; + wine_dbg_vlog( dbcl, __wine_dbch___default, __func__, fmt, va_args ); +} + +static const char *debugstr_version( UINT version ) +{ + return wine_dbg_sprintf("%u.%u.%u", AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version), AV_VERSION_MICRO(version)); +} + +static NTSTATUS process_attach( void *arg ) +{ + TRACE( "FFmpeg support:\n" ); + TRACE( " avutil version %s\n", debugstr_version( avutil_version() ) ); + + av_log_set_callback( vlog ); + return STATUS_SUCCESS; +} + +#else /* ENABLE_FFMPEG */ + #define MAKE_UNSUPPORTED_ENTRY( name ) \ static NTSTATUS name( void *arg ) \ { \ + WARN( "FFmpeg support not compiled in\n" ); \ return STATUS_NOT_SUPPORTED; \ } MAKE_UNSUPPORTED_ENTRY( process_attach ) #undef MAKE_UNSUPPORTED_ENTRY
+#endif /* ENABLE_FFMPEG */ + const unixlib_entry_t __wine_unix_call_funcs[] = { #define X( name ) [unix_##name] = name
From: Rémi Bernon rbernon@codeweavers.com
--- configure.ac | 5 +++- dlls/winedmo/Makefile.in | 2 ++ dlls/winedmo/main.c | 13 ++++++++++ dlls/winedmo/unix_demuxer.c | 52 +++++++++++++++++++++++++++++++++++++ dlls/winedmo/unix_private.h | 5 ++++ dlls/winedmo/unixlib.c | 17 ++++++++++++ dlls/winedmo/unixlib.h | 10 +++++++ dlls/winedmo/winedmo.spec | 2 +- include/Makefile.in | 1 + include/wine/winedmo.h | 31 ++++++++++++++++++++++ 10 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 dlls/winedmo/unix_demuxer.c create mode 100644 include/wine/winedmo.h
diff --git a/configure.ac b/configure.ac index 01949a711ab..e685aa52034 100644 --- a/configure.ac +++ b/configure.ac @@ -1634,9 +1634,12 @@ WINE_NOTICE_WITH(pulse, [test -z "$PULSE_LIBS"], dnl **** Check for FFmpeg **** if test "x$with_ffmpeg" != "xno"; then - WINE_PACKAGE_FLAGS(FFMPEG,[libavutil],,,, + WINE_PACKAGE_FLAGS(FFMPEG,[libavutil libavformat],,,, [AC_CHECK_HEADER([libavutil/avutil.h], [AC_CHECK_LIB(avutil,av_log_set_callback,[:],[FFMPEG_LIBS=""],[$FFMPEG_LIBS])], + [FFMPEG_LIBS=""]) + AC_CHECK_HEADER([libavformat/avformat.h], + [AC_CHECK_LIB(avformat,av_find_input_format,[:],[FFMPEG_LIBS=""],[$FFMPEG_LIBS])], [FFMPEG_LIBS=""])]) if test "x$FFMPEG_LIBS" != "x"; then diff --git a/dlls/winedmo/Makefile.in b/dlls/winedmo/Makefile.in index 939941884e8..5b816357770 100644 --- a/dlls/winedmo/Makefile.in +++ b/dlls/winedmo/Makefile.in @@ -1,8 +1,10 @@ MODULE = winedmo.dll UNIXLIB = winedmo.so +IMPORTLIB = winedmo UNIX_CFLAGS = $(FFMPEG_CFLAGS) UNIX_LIBS = $(FFMPEG_LIBS) $(PTHREAD_LIBS)
SOURCES = \ main.c \ + unix_demuxer.c \ unixlib.c diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 1e6c074b068..b0913be044e 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -43,3 +43,16 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
return TRUE; } + + +NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ) +{ + struct demuxer_check_params params = {0}; + NTSTATUS status; + + TRACE( "mime_type %s\n", debugstr_a(mime_type) ); + lstrcpynA( params.mime_type, mime_type, sizeof(params.mime_type) ); + + if ((status = UNIX_CALL( demuxer_check, ¶ms ))) WARN( "returning %#lx\n", status ); + return status; +} diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c new file mode 100644 index 00000000000..3a4a74b304e --- /dev/null +++ b/dlls/winedmo/unix_demuxer.c @@ -0,0 +1,52 @@ +/* + * Copyright 2024 Rémi Bernon for CodeWeavers + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" +#include "unix_private.h" + +#include "wine/debug.h" + +#ifdef ENABLE_FFMPEG + +WINE_DEFAULT_DEBUG_CHANNEL(dmo); + +NTSTATUS demuxer_check( void *arg ) +{ + struct demuxer_check_params *params = arg; + const AVInputFormat *format = NULL; + + if (!strcmp( params->mime_type, "video/mp4" )) format = av_find_input_format( "mp4" ); + else if (!strcmp( params->mime_type, "video/avi" )) format = av_find_input_format( "avi" ); + else if (!strcmp( params->mime_type, "audio/wav" )) format = av_find_input_format( "wav" ); + else if (!strcmp( params->mime_type, "audio/x-ms-wma" )) format = av_find_input_format( "asf" ); + else if (!strcmp( params->mime_type, "video/x-ms-wmv" )) format = av_find_input_format( "asf" ); + else if (!strcmp( params->mime_type, "video/x-ms-asf" )) format = av_find_input_format( "asf" ); + else if (!strcmp( params->mime_type, "video/mpeg" )) format = av_find_input_format( "mpeg" ); + else if (!strcmp( params->mime_type, "audio/mp3" )) format = av_find_input_format( "mp3" ); + + if (format) TRACE( "Found format %s (%s)\n", format->name, format->long_name ); + else FIXME( "Unsupported MIME type %s\n", debugstr_a(params->mime_type) ); + + return format ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED; +} + +#endif /* ENABLE_FFMPEG */ diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index 8e97cede3f8..5e38ecb4a60 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -31,5 +31,10 @@ #ifdef ENABLE_FFMPEG
#include <libavutil/avutil.h> +#include <libavutil/imgutils.h> +#include <libavformat/avformat.h> + +/* unix_demuxer.c */ +extern NTSTATUS demuxer_check( void * );
#endif /* ENABLE_FFMPEG */ diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 83fc8e01e91..523d3199ab1 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -53,8 +53,20 @@ static const char *debugstr_version( UINT version )
static NTSTATUS process_attach( void *arg ) { + const AVInputFormat *demuxer; + void *opaque; + TRACE( "FFmpeg support:\n" ); TRACE( " avutil version %s\n", debugstr_version( avutil_version() ) ); + TRACE( " avformat version %s\n", debugstr_version( avformat_version() ) ); + + TRACE( "available demuxers:\n" ); + for (opaque = NULL; (demuxer = av_demuxer_iterate( &opaque ));) + { + TRACE( " %s (%s)\n", demuxer->name, demuxer->long_name ); + if (demuxer->extensions) TRACE( " extensions: %s\n", demuxer->extensions ); + if (demuxer->mime_type) TRACE( " mime_types: %s\n", demuxer->mime_type ); + }
av_log_set_callback( vlog ); return STATUS_SUCCESS; @@ -69,6 +81,7 @@ static NTSTATUS process_attach( void *arg ) return STATUS_NOT_SUPPORTED; \ } MAKE_UNSUPPORTED_ENTRY( process_attach ) +MAKE_UNSUPPORTED_ENTRY( demuxer_check ) #undef MAKE_UNSUPPORTED_ENTRY
#endif /* ENABLE_FFMPEG */ @@ -77,6 +90,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { #define X( name ) [unix_##name] = name X( process_attach ), + + X( demuxer_check ), };
C_ASSERT(ARRAY_SIZE(__wine_unix_call_funcs) == unix_funcs_count); @@ -87,6 +102,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { #define X64( name ) [unix_##name] = wow64_##name X( process_attach ), + + X( demuxer_check ), };
C_ASSERT(ARRAY_SIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count); diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index c1b0542f33b..d71d570c335 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -27,9 +27,19 @@
#include "wine/unixlib.h"
+ +struct demuxer_check_params +{ + char mime_type[256]; +}; + + enum unix_funcs { unix_process_attach, + + unix_demuxer_check, + unix_funcs_count, };
diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 76421d7e35b..661703b6c50 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1 +1 @@ -# nothing to export +@ cdecl winedmo_demuxer_check(str) diff --git a/include/Makefile.in b/include/Makefile.in index 000214484ed..8d25e40ba05 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -940,6 +940,7 @@ SOURCES = \ wine/windef16.h \ wine/wine_common_ver.rc \ wine/wined3d.h \ + wine/winedmo.h \ wine/winedxgi.idl \ wine/wingdi16.h \ wine/winnet16.h \ diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h new file mode 100644 index 00000000000..06ac1e04261 --- /dev/null +++ b/include/wine/winedmo.h @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Rémi Bernon for CodeWeavers + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINEDMO_H +#define __WINE_WINEDMO_H + +#include <stddef.h> +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winternl.h" + +NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ); + +#endif /* __WINE_WINEDMO_H */
From: Rémi Bernon rbernon@codeweavers.com
This introduces a new alternative FFmpeg-based implementation for the MF byte stream handlers, while keeping the current GStreamer-based as default.
The new implementation can be enabled by setting the DWORD value:
DisableGstByteStreamHandler = 1
in the HKCU\Software\Wine\MediaFoundation registry key. --- dlls/mfasfsrcsnk/Makefile.in | 2 +- dlls/mfmp4srcsnk/Makefile.in | 2 +- dlls/mfsrcsnk/Makefile.in | 2 +- dlls/mfsrcsnk/media_source.c | 71 ++++++++++++++++++++++++++++++++---- 4 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/dlls/mfasfsrcsnk/Makefile.in b/dlls/mfasfsrcsnk/Makefile.in index f450c304d3b..e2dbc7afb4d 100644 --- a/dlls/mfasfsrcsnk/Makefile.in +++ b/dlls/mfasfsrcsnk/Makefile.in @@ -1,5 +1,5 @@ MODULE = mfasfsrcsnk.dll -IMPORTS = ole32 mfplat mfuuid uuid +IMPORTS = advapi32 ole32 mfplat mfuuid uuid winedmo PARENTSRC = ../mfsrcsnk
EXTRADLLFLAGS = -Wb,--prefer-native diff --git a/dlls/mfmp4srcsnk/Makefile.in b/dlls/mfmp4srcsnk/Makefile.in index cc91ab58df9..5464e1d86e3 100644 --- a/dlls/mfmp4srcsnk/Makefile.in +++ b/dlls/mfmp4srcsnk/Makefile.in @@ -1,5 +1,5 @@ MODULE = mfmp4srcsnk.dll -IMPORTS = ole32 mfplat mfuuid uuid +IMPORTS = advapi32 ole32 mfplat mfuuid uuid winedmo PARENTSRC = ../mfsrcsnk
EXTRADLLFLAGS = -Wb,--prefer-native diff --git a/dlls/mfsrcsnk/Makefile.in b/dlls/mfsrcsnk/Makefile.in index d238b43424d..5bef58ca10d 100644 --- a/dlls/mfsrcsnk/Makefile.in +++ b/dlls/mfsrcsnk/Makefile.in @@ -1,6 +1,6 @@ MODULE = mfsrcsnk.dll IMPORTLIB = mfsrcsnk -IMPORTS = ole32 mfplat mfuuid uuid +IMPORTS = advapi32 ole32 mfplat mfuuid uuid winedmo
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 8c02743e811..fe6f8cea256 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -19,12 +19,43 @@ #include "mfsrcsnk_private.h"
#include "wine/debug.h" +#include "wine/winedmo.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + +static HRESULT byte_stream_plugin_create(IUnknown *outer, REFIID riid, void **out) +{ + FIXME("outer %p, riid %s, out %p stub!.\n", outer, debugstr_guid(riid), out); + *out = NULL; + return E_NOTIMPL; +} + +static BOOL use_gst_byte_stream_handler(void) +{ + BOOL result; + DWORD size = sizeof(result); + + /* @@ Wine registry key: HKCU\Software\Wine\MediaFoundation */ + if (!RegGetValueW( HKEY_CURRENT_USER, L"Software\Wine\MediaFoundation", L"DisableGstByteStreamHandler", + RRF_RT_REG_DWORD, NULL, &result, &size )) + return !result; + + return TRUE; +}
static HRESULT WINAPI asf_byte_stream_plugin_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out) { - static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; - return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + NTSTATUS status; + + if ((status = winedmo_demuxer_check("video/x-ms-asf")) || use_gst_byte_stream_handler()) + { + static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; + if (status) WARN("Unsupported demuxer, status %#lx.\n", status); + return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + } + + return byte_stream_plugin_create(outer, riid, out); }
static const IClassFactoryVtbl asf_byte_stream_plugin_factory_vtbl = @@ -41,8 +72,16 @@ IClassFactory asf_byte_stream_plugin_factory = {&asf_byte_stream_plugin_factory_ static HRESULT WINAPI avi_byte_stream_plugin_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out) { - static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; - return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + NTSTATUS status; + + if ((status = winedmo_demuxer_check("video/avi")) || use_gst_byte_stream_handler()) + { + static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; + if (status) WARN("Unsupported demuxer, status %#lx.\n", status); + return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + } + + return byte_stream_plugin_create(outer, riid, out); }
static const IClassFactoryVtbl avi_byte_stream_plugin_factory_vtbl = @@ -59,8 +98,16 @@ IClassFactory avi_byte_stream_plugin_factory = {&avi_byte_stream_plugin_factory_ static HRESULT WINAPI mpeg4_byte_stream_plugin_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out) { - static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; - return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + NTSTATUS status; + + if ((status = winedmo_demuxer_check("video/mp4")) || use_gst_byte_stream_handler()) + { + static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; + if (status) WARN("Unsupported demuxer, status %#lx.\n", status); + return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + } + + return byte_stream_plugin_create(outer, riid, out); }
static const IClassFactoryVtbl mpeg4_byte_stream_plugin_factory_vtbl = @@ -77,8 +124,16 @@ IClassFactory mpeg4_byte_stream_plugin_factory = {&mpeg4_byte_stream_plugin_fact static HRESULT WINAPI wav_byte_stream_plugin_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out) { - static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; - return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + NTSTATUS status; + + if ((status = winedmo_demuxer_check("audio/wav")) || use_gst_byte_stream_handler()) + { + static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618,0x5e5a,0x468a,{0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62}}; + if (status) WARN("Unsupported demuxer, status %#lx.\n", status); + return CoCreateInstance(&CLSID_GStreamerByteStreamHandler, outer, CLSCTX_INPROC_SERVER, riid, out); + } + + return byte_stream_plugin_create(outer, riid, out); }
static const IClassFactoryVtbl wav_byte_stream_plugin_factory_vtbl =
Jinoh Kang (@iamahuman) commented about dlls/winedmo/unixlib.c:
+#define X( name ) [unix_##name] = name
- X( process_attach ),
- X( demuxer_check ),
+};
+C_ASSERT(ARRAY_SIZE(__wine_unix_call_funcs) == unix_funcs_count);
+#ifdef _WIN64
+const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ +#define X64( name ) [unix_##name] = wow64_##name
- X( process_attach ),
- X( demuxer_check ),
```suggestion:-3+0 #define X64( name ) [unix_##name] = wow64_##name X64( process_attach ),
X64( demuxer_check ), ```
On Wed Sep 4 13:14:47 2024 +0000, Jinoh Kang wrote:
#define X64( name ) [unix_##name] = wow64_##name X64( process_attach ), X64( demuxer_check ),
Uh, no? The macro isn't used yet, but it will be later. I could've split it differently but i don't think it matters so much.
On Wed Sep 4 13:22:56 2024 +0000, Rémi Bernon wrote:
Uh, no? The macro isn't used yet, but it will be later. I could've split it differently but i don't think it matters so much.
X64 means the argument struct is different for 32bit and 64bit callers, and needs to be converted if the caller is 32bit and callee is 64bit (aka new-style wow64). In practice, this is means 'does the argument struct contain any pointers or pointer-sized objects?'.
These don't. One just contains a char array, and the other isn't used at all.
So, no, these should not be X64. The unused macro looks a little silly, but every other wow64_funcs table in other unixlibs has the same macro; removing it would be inconsistent, which is also silly.
And, as mentioned, it will be used later.
Will this fix any bug not already fixed by 5988?
Yes, it will make stream order and demuxing completely deterministic, which is required for proper Spyro language selection, and solve the various deadlocks that keep happening in the GStreamer-based media source.
It's also faster to initialize and detect streams than what I had with GStreamer, and ~20x times faster than !5988, under a millisecond and pretty much like Windows on some given hardware.
5988 achieves deterministic ordering according to my testing.
and solve the various deadlocks that keep happening in the GStreamer-based media source.
Which deadlocks?
It's also faster to initialize and detect streams than what I had with GStreamer, and ~20x times faster than !5988, under a millisecond and pretty much like Windows on some given hardware.
Which media files are you seeing this with? I'm seeing creation time under 1 ms with 5988, which is already faster than the time given for Windows, and fast enough to fix the application bugs mentioned.
I also hope this implement will eventually fix various game video render issue under winegstreamer. I have see various game only has audio render. has no video render. but normal in proton wine implement