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.
-- v3: mfsrcsnk: Stub byte stream handlers if demuxing is supported. winedmo: Export a new winedmo_demuxer_check function. winedmo: Link and initialize FFmpeg on load. winedmo: Load a unixlib on process attach. winedmo: Introduce a new internal DLL.
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 | 31 +++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+)
diff --git a/configure.ac b/configure.ac index 8b44370122f..ac08b321c3e 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 + AC_DEFINE(HAVE_FFMPEG, 1, [Define to 1 if you have the FFmpeg libraries]) + 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..83e2070444e 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -27,3 +27,9 @@ #include "winbase.h"
#include "unixlib.h" + +#ifdef HAVE_FFMPEG + +#include <libavutil/avutil.h> + +#endif /* HAVE_FFMPEG */ diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 7d27e031e37..3a351da64a9 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -26,14 +26,45 @@
#include "wine/debug.h"
+WINE_DEFAULT_DEBUG_CHANNEL(dmo); + +#ifdef HAVE_FFMPEG + +static void vlog( void *ctx, int level, const char *fmt, va_list va_args ) +{ + enum __wine_debug_class dbcl = __WINE_DBCL_TRACE; + 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 /* HAVE_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 /* HAVE_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 ac08b321c3e..14124016e9d 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..1abb173fdc7 --- /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 HAVE_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 /* HAVE_FFMPEG */ diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index 83e2070444e..81c38aa12d2 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -31,5 +31,10 @@ #ifdef HAVE_FFMPEG
#include <libavutil/avutil.h> +#include <libavutil/imgutils.h> +#include <libavformat/avformat.h> + +/* unix_demuxer.c */ +extern NTSTATUS demuxer_check( void * );
#endif /* HAVE_FFMPEG */ diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 3a351da64a9..0279714a584 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -45,8 +45,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; @@ -61,6 +73,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 /* HAVE_FFMPEG */ @@ -69,6 +82,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); @@ -79,6 +94,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 =
On Tue Sep 10 00:17:28 2024 +0000, Chunhao Hung wrote:
I have tested that branch before. somehow it stuck on audio decode for some reason, I do not know If that is my merge method incorrect or a BUG
The dependencies are the FFmpeg libraries (libavutil-dev, libavformat-dev, libavcodec-dev, libswscale-dev, libswresample-dev). Note that the branch is probably not ready to be used, it was only an experiment to check whether we could use it fully and pass most of our tests.
The next question is whether winedmo is really useful without ffmpeg, or if it should simply not be built at all.
I have thought about it and I think it makes it easier for frontends as they can simply statically link with it, and it also makes runtime decisions on which backend to use simpler. If the unixlib fails to load, or was not built with FFmpeg support then it will be reported to the callers and they can either return the error or try to use something else.
Also, I have tried implementing alternative decoding path for cases where the system FFmpeg is crippled, for instance targetting macOS videotoolbox directly, and I don't think it's necessarily limited to FFmpeg, though it still uses libavutil because it's simpler to use the AVFrame/AVPacket structures internally.
Then at least the fallbacks need to be on the PE side, we can't call the Unix side if the unixlib failed to load.