[PATCH v2 0/4] MR9913: Draft: winedmo: Allow building against multiple and specific FFmpeg versions.
This would achieve ABI compatibility with arbitrary FFmpeg versions, without having to redefine / fixup FFmpeg structures manually. Downstream Wine distributions may be interested in having an embedded but crippled FFmpeg shipped with them, avoiding issues related to FFmpeg distribution, while still being able to dynamically load the system, or externally provided, more capable FFmpeg version. The distributions would only need to build every supported winedmo versions, targeting the corresponding FFmpeg ABI, to later dynamically load them. The non-versioned winedmo would load the distribution embedded FFmpeg for instance, while the versioned modules would target a matching system library. This also introduces an unified interface with winegstreamer, allowing us to get rid of the duplicated media source code. -- v2: winedmo: Load winedmo for specific FFmpeg versions dynamically. winedmo: Allow building winedmo against multiple FFmpeg versions. winedmo: Expose function tables instead of individual functions. mfsrcsnk: Use function pointers for winedmo demuxer functions. https://gitlab.winehq.org/wine/wine/-/merge_requests/9913
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/mfsrcsnk/media_source.c | 140 ++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 53 deletions(-) diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index b084db6ee6b..a67abd877c9 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -26,6 +26,54 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat); +struct winedmo_demuxer_funcs +{ + NTSTATUS (*CDECL create)( const WCHAR *url, struct winedmo_stream *stream, UINT64 stream_size, INT64 *duration, + UINT *stream_count, WCHAR *mime_type, struct winedmo_demuxer *demuxer ); + NTSTATUS (*CDECL destroy)( struct winedmo_demuxer *demuxer ); + NTSTATUS (*CDECL read)( struct winedmo_demuxer demuxer, UINT *stream, DMO_OUTPUT_DATA_BUFFER *buffer, UINT *buffer_size ); + NTSTATUS (*CDECL seek)( struct winedmo_demuxer demuxer, INT64 timestamp ); + NTSTATUS (*CDECL stream_lang)( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); + NTSTATUS (*CDECL stream_name)( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); + NTSTATUS (*CDECL stream_type)( struct winedmo_demuxer demuxer, UINT stream, + GUID *major, union winedmo_format **format ); +}; + +static const struct winedmo_demuxer_funcs winedmo_demuxer_funcs = +{ + winedmo_demuxer_create, + winedmo_demuxer_destroy, + winedmo_demuxer_read, + winedmo_demuxer_seek, + winedmo_demuxer_stream_lang, + winedmo_demuxer_stream_name, + winedmo_demuxer_stream_type, +}; + +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 const struct winedmo_demuxer_funcs *get_demuxer_funcs(const char *mime_type) +{ + if (use_gst_byte_stream_handler()) + return NULL; + + if (!winedmo_demuxer_check(mime_type)) + return &winedmo_demuxer_funcs; + + return NULL; +} + #define DEFINE_MF_ASYNC_PARAMS(type) \ static struct type *type ## _from_IUnknown(IUnknown *iface) \ { \ @@ -271,6 +319,7 @@ struct media_source float rate; BOOL thin; + const struct winedmo_demuxer_funcs *funcs; struct winedmo_demuxer winedmo_demuxer; struct winedmo_stream winedmo_stream; UINT64 file_size; @@ -496,7 +545,7 @@ static HRESULT media_source_start(struct media_source *source, IMFPresentationDe media_stream_start(stream, source->stream_map[i], position); } - if (position->vt == VT_I8 && (status = winedmo_demuxer_seek(source->winedmo_demuxer, position->hVal.QuadPart))) + if (position->vt == VT_I8 && (status = source->funcs->seek(source->winedmo_demuxer, position->hVal.QuadPart))) WARN("Failed to seek to %I64d, status %#lx\n", position->hVal.QuadPart, status); source->state = SOURCE_RUNNING; @@ -637,7 +686,7 @@ static HRESULT create_media_buffer_sample(UINT buffer_size, IMFSample **sample, return hr; } -static HRESULT demuxer_read_sample(struct winedmo_demuxer demuxer, UINT *index, IMFSample **out) +static HRESULT source_demuxer_read_sample(struct media_source *source, UINT *index, IMFSample **out) { UINT buffer_size = 0x1000; IMFSample *sample; @@ -650,7 +699,7 @@ static HRESULT demuxer_read_sample(struct winedmo_demuxer demuxer, UINT *index, if (FAILED(hr = create_media_buffer_sample(buffer_size, &sample, &output.pBuffer))) return hr; - if ((status = winedmo_demuxer_read(demuxer, index, &output, &buffer_size))) + if ((status = source->funcs->read(source->winedmo_demuxer, index, &output, &buffer_size))) { if (status == STATUS_BUFFER_TOO_SMALL) hr = E_PENDING; else if (status == STATUS_END_OF_FILE) hr = MF_E_END_OF_STREAM; @@ -696,7 +745,7 @@ static HRESULT media_source_read(struct media_source *source) if (source->state != SOURCE_RUNNING) return S_OK; - if (FAILED(hr = demuxer_read_sample(source->winedmo_demuxer, &index, &sample)) && hr != MF_E_END_OF_STREAM) + if (FAILED(hr = source_demuxer_read_sample(source, &index, &sample)) && hr != MF_E_END_OF_STREAM) { WARN("Failed to read stream %u data, hr %#lx\n", index, hr); return hr; @@ -1255,7 +1304,7 @@ static ULONG WINAPI media_source_Release(IMFMediaSource *iface) { IMFMediaSource_Shutdown(iface); - winedmo_demuxer_destroy(&source->winedmo_demuxer); + source->funcs->destroy(&source->winedmo_demuxer); free(source->stream_map); free(source->streams); @@ -1524,15 +1573,15 @@ static HRESULT media_type_from_winedmo_format( GUID major, union winedmo_format return E_NOTIMPL; } -static HRESULT get_stream_media_type(struct winedmo_demuxer demuxer, UINT index, GUID *major, IMFMediaType **media_type) +static HRESULT get_stream_media_type(struct media_source *source, UINT index, GUID *major, IMFMediaType **media_type) { union winedmo_format *format; NTSTATUS status; HRESULT hr; - TRACE("demuxer %p, index %u, media_type %p\n", &demuxer, index, media_type); + TRACE("source %p, index %u, media_type %p\n", source, index, media_type); - if ((status = winedmo_demuxer_stream_type(demuxer, index, major, &format))) + if ((status = source->funcs->stream_type(source->winedmo_demuxer, index, major, &format))) { WARN("Failed to get stream %u type, status %#lx\n", index, status); return HRESULT_FROM_NT(status); @@ -1554,7 +1603,7 @@ static void media_source_init_stream_map(struct media_source *source, UINT strea { for (i = 0; i < stream_count; i++) { - if (FAILED(get_stream_media_type(source->winedmo_demuxer, i, &major, NULL))) + if (FAILED(get_stream_media_type(source, i, &major, NULL))) continue; TRACE("mapping source %p stream %u to demuxer stream %u\n", source, n, i); source->stream_map[n++] = i; @@ -1564,7 +1613,7 @@ static void media_source_init_stream_map(struct media_source *source, UINT strea for (i = stream_count - 1; i >= 0; i--) { - if (FAILED(get_stream_media_type(source->winedmo_demuxer, i, &major, NULL))) + if (FAILED(get_stream_media_type(source, i, &major, NULL))) continue; if (IsEqualGUID(&major, &MFMediaType_Audio)) { @@ -1574,7 +1623,7 @@ static void media_source_init_stream_map(struct media_source *source, UINT strea } for (i = stream_count - 1; i >= 0; i--) { - if (FAILED(get_stream_media_type(source->winedmo_demuxer, i, &major, NULL))) + if (FAILED(get_stream_media_type(source, i, &major, NULL))) continue; if (IsEqualGUID(&major, &MFMediaType_Video)) { @@ -1584,7 +1633,7 @@ static void media_source_init_stream_map(struct media_source *source, UINT strea } for (i = stream_count - 1; i >= 0; i--) { - if (FAILED(get_stream_media_type(source->winedmo_demuxer, i, &major, NULL))) + if (FAILED(get_stream_media_type(source, i, &major, NULL))) major = GUID_NULL; if (!IsEqualGUID(&major, &MFMediaType_Audio) && !IsEqualGUID(&major, &MFMediaType_Video)) { @@ -1649,15 +1698,15 @@ static void media_source_init_descriptors(struct media_source *source) NTSTATUS status; GUID major; - if ((status = winedmo_demuxer_stream_lang(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) + if (FAILED(status = source->funcs->stream_lang(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) || (!wcscmp(source->mime_type, L"video/mp4") && FAILED(normalize_mp4_language_code(source, buffer))) || FAILED(IMFStreamDescriptor_SetString(stream->descriptor, &MF_SD_LANGUAGE, buffer))) WARN("Failed to set stream descriptor language, status %#lx\n", status); - if ((status = winedmo_demuxer_stream_name(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) + if (FAILED(status = source->funcs->stream_name(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) || FAILED(IMFStreamDescriptor_SetString(stream->descriptor, &MF_SD_STREAM_NAME, buffer))) WARN("Failed to set stream descriptor name, status %#lx\n", status); - if (FAILED(get_stream_media_type(source->winedmo_demuxer, source->stream_map[i], &major, NULL))) + if (FAILED(get_stream_media_type(source, source->stream_map[i], &major, NULL))) continue; if (IsEqualGUID(&major, &MFMediaType_Audio)) @@ -1767,7 +1816,7 @@ static HRESULT media_source_async_create(struct media_source *source, IMFAsyncRe source->winedmo_stream.p_seek = media_source_seek_cb; source->winedmo_stream.p_read = media_source_read_cb; - if ((status = winedmo_demuxer_create(source->url, &source->winedmo_stream, source->file_size, &source->duration, + if ((status = source->funcs->create(source->url, &source->winedmo_stream, source->file_size, &source->duration, &stream_count, source->mime_type, &source->winedmo_demuxer))) { WARN("Failed to create demuxer, status %#lx\n", status); @@ -1790,7 +1839,7 @@ static HRESULT media_source_async_create(struct media_source *source, IMFAsyncRe IMFMediaType *media_type; GUID major; - if (FAILED(hr = get_stream_media_type(source->winedmo_demuxer, source->stream_map[i], &major, &media_type))) + if (FAILED(hr = get_stream_media_type(source, source->stream_map[i], &major, &media_type))) continue; if (SUCCEEDED(hr = stream_descriptor_create(i + 1, media_type, &descriptor))) { @@ -1832,7 +1881,7 @@ static WCHAR *get_byte_stream_url(IMFByteStream *stream, const WCHAR *url) return url ? wcsdup(url) : NULL; } -static HRESULT media_source_create(const WCHAR *url, IMFByteStream *stream, IMFMediaSource **out) +static HRESULT media_source_create(const struct winedmo_demuxer_funcs *funcs, const WCHAR *url, IMFByteStream *stream, IMFMediaSource **out) { struct media_source *source; HRESULT hr; @@ -1852,6 +1901,7 @@ static HRESULT media_source_create(const WCHAR *url, IMFByteStream *stream, IMFM source->async_read_iface.lpVtbl = &media_source_async_read_vtbl; source->async_set_rate_iface.lpVtbl = &media_source_async_set_rate_vtbl; source->refcount = 1; + source->funcs = funcs; if (FAILED(hr = MFCreateEventQueue(&source->queue))) { @@ -1875,6 +1925,7 @@ struct byte_stream_handler { IMFByteStreamHandler IMFByteStreamHandler_iface; LONG refcount; + const struct winedmo_demuxer_funcs *funcs; }; static struct byte_stream_handler *byte_stream_handler_from_IMFByteStreamHandler(IMFByteStreamHandler *iface) @@ -1946,7 +1997,7 @@ static HRESULT WINAPI byte_stream_handler_BeginCreateObject(IMFByteStreamHandler return MF_E_BYTESTREAM_NOT_SEEKABLE; } - if (FAILED(hr = media_source_create(url, stream, &source))) + if (FAILED(hr = media_source_create(handler->funcs, url, stream, &source))) return hr; if (SUCCEEDED(hr = MFCreateAsyncResult((IUnknown *)source, callback, state, &result))) { @@ -2004,7 +2055,7 @@ static const IMFByteStreamHandlerVtbl byte_stream_handler_vtbl = byte_stream_handler_GetMaxNumberOfBytesRequiredForResolution, }; -static HRESULT byte_stream_plugin_create(IUnknown *outer, REFIID riid, void **out) +static HRESULT byte_stream_plugin_create(const struct winedmo_demuxer_funcs *funcs, IUnknown *outer, REFIID riid, void **out) { struct byte_stream_handler *handler; HRESULT hr; @@ -2017,6 +2068,7 @@ static HRESULT byte_stream_plugin_create(IUnknown *outer, REFIID riid, void **ou return E_OUTOFMEMORY; handler->IMFByteStreamHandler_iface.lpVtbl = &byte_stream_handler_vtbl; handler->refcount = 1; + handler->funcs = funcs; TRACE("created %p\n", handler); hr = IMFByteStreamHandler_QueryInterface(&handler->IMFByteStreamHandler_iface, riid, out); @@ -2024,32 +2076,18 @@ static HRESULT byte_stream_plugin_create(IUnknown *outer, REFIID riid, void **ou return hr; } -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) { - NTSTATUS status; + const struct winedmo_demuxer_funcs *funcs; - if ((status = winedmo_demuxer_check("video/x-ms-asf")) || use_gst_byte_stream_handler()) + if (!(funcs = get_demuxer_funcs("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); + return byte_stream_plugin_create(funcs, outer, riid, out); } static const IClassFactoryVtbl asf_byte_stream_plugin_factory_vtbl = @@ -2066,16 +2104,15 @@ 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) { - NTSTATUS status; + const struct winedmo_demuxer_funcs *funcs; - if ((status = winedmo_demuxer_check("video/avi")) || use_gst_byte_stream_handler()) + if (!(funcs = get_demuxer_funcs("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); + return byte_stream_plugin_create(funcs, outer, riid, out); } static const IClassFactoryVtbl avi_byte_stream_plugin_factory_vtbl = @@ -2092,16 +2129,15 @@ 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) { - NTSTATUS status; + const struct winedmo_demuxer_funcs *funcs; - if ((status = winedmo_demuxer_check("video/mp4")) || use_gst_byte_stream_handler()) + if (!(funcs = get_demuxer_funcs("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); + return byte_stream_plugin_create(funcs, outer, riid, out); } static const IClassFactoryVtbl mpeg4_byte_stream_plugin_factory_vtbl = @@ -2118,16 +2154,15 @@ 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) { - NTSTATUS status; + const struct winedmo_demuxer_funcs *funcs; - if ((status = winedmo_demuxer_check("audio/wav")) || use_gst_byte_stream_handler()) + if (!(funcs = get_demuxer_funcs("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); + return byte_stream_plugin_create(funcs, outer, riid, out); } static const IClassFactoryVtbl wav_byte_stream_plugin_factory_vtbl = @@ -2144,16 +2179,15 @@ IClassFactory wav_byte_stream_plugin_factory = {&wav_byte_stream_plugin_factory_ static HRESULT WINAPI mp3_byte_stream_plugin_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **out) { - NTSTATUS status; + const struct winedmo_demuxer_funcs *funcs; - if ((status = winedmo_demuxer_check("audio/mp3")) || use_gst_byte_stream_handler()) + if (!(funcs = get_demuxer_funcs("audio/mp3")) || 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); + return byte_stream_plugin_create(funcs, outer, riid, out); } static const IClassFactoryVtbl mp3_byte_stream_plugin_factory_vtbl = -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9913
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/mfsrcsnk/media_source.c | 29 +--------------- dlls/winedmo/main.c | 66 ++++++++++++++++++++++++------------ dlls/winedmo/winedmo.spec | 9 +---- include/wine/winedmo.h | 25 ++++++++------ 4 files changed, 62 insertions(+), 67 deletions(-) diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index a67abd877c9..0f7cdd4e2b2 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -26,30 +26,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat); -struct winedmo_demuxer_funcs -{ - NTSTATUS (*CDECL create)( const WCHAR *url, struct winedmo_stream *stream, UINT64 stream_size, INT64 *duration, - UINT *stream_count, WCHAR *mime_type, struct winedmo_demuxer *demuxer ); - NTSTATUS (*CDECL destroy)( struct winedmo_demuxer *demuxer ); - NTSTATUS (*CDECL read)( struct winedmo_demuxer demuxer, UINT *stream, DMO_OUTPUT_DATA_BUFFER *buffer, UINT *buffer_size ); - NTSTATUS (*CDECL seek)( struct winedmo_demuxer demuxer, INT64 timestamp ); - NTSTATUS (*CDECL stream_lang)( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); - NTSTATUS (*CDECL stream_name)( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); - NTSTATUS (*CDECL stream_type)( struct winedmo_demuxer demuxer, UINT stream, - GUID *major, union winedmo_format **format ); -}; - -static const struct winedmo_demuxer_funcs winedmo_demuxer_funcs = -{ - winedmo_demuxer_create, - winedmo_demuxer_destroy, - winedmo_demuxer_read, - winedmo_demuxer_seek, - winedmo_demuxer_stream_lang, - winedmo_demuxer_stream_name, - winedmo_demuxer_stream_type, -}; - static BOOL use_gst_byte_stream_handler(void) { BOOL result; @@ -68,10 +44,7 @@ static const struct winedmo_demuxer_funcs *get_demuxer_funcs(const char *mime_ty if (use_gst_byte_stream_handler()) return NULL; - if (!winedmo_demuxer_check(mime_type)) - return &winedmo_demuxer_funcs; - - return NULL; + return winedmo_get_demuxer_funcs(mime_type, WINEDMO_DEMUXER_VERSION); } #define DEFINE_MF_ASYNC_PARAMS(type) \ diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 671e632b16d..27263b64826 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -159,20 +159,9 @@ static void buffer_unlock( DMO_OUTPUT_DATA_BUFFER *buffer, struct sample *sample } -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; -} - -NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream *stream, UINT64 stream_size, INT64 *duration, - UINT *stream_count, WCHAR *mime_type, struct winedmo_demuxer *demuxer ) +static NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream *stream, + UINT64 stream_size, INT64 *duration, UINT *stream_count, + WCHAR *mime_type, struct winedmo_demuxer *demuxer ) { struct demuxer_create_params params = {0}; char *tmp = NULL; @@ -208,7 +197,7 @@ NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream * return STATUS_SUCCESS; } -NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer ) +static NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer ) { struct demuxer_destroy_params params = {.demuxer = *demuxer}; NTSTATUS status; @@ -225,7 +214,8 @@ NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer ) return status; } -NTSTATUS CDECL winedmo_demuxer_read( struct winedmo_demuxer demuxer, UINT *stream, DMO_OUTPUT_DATA_BUFFER *buffer, UINT *buffer_size ) +static NTSTATUS CDECL winedmo_demuxer_read( struct winedmo_demuxer demuxer, UINT *stream, + DMO_OUTPUT_DATA_BUFFER *buffer, UINT *buffer_size ) { struct demuxer_read_params params = {.demuxer = demuxer}; NTSTATUS status; @@ -249,7 +239,7 @@ NTSTATUS CDECL winedmo_demuxer_read( struct winedmo_demuxer demuxer, UINT *strea return status; } -NTSTATUS CDECL winedmo_demuxer_seek( struct winedmo_demuxer demuxer, INT64 timestamp ) +static NTSTATUS CDECL winedmo_demuxer_seek( struct winedmo_demuxer demuxer, INT64 timestamp ) { struct demuxer_seek_params params = {.demuxer = demuxer, .timestamp = timestamp}; NTSTATUS status; @@ -265,7 +255,7 @@ NTSTATUS CDECL winedmo_demuxer_seek( struct winedmo_demuxer demuxer, INT64 times return STATUS_SUCCESS; } -NTSTATUS CDECL winedmo_demuxer_stream_lang( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ) +static NTSTATUS CDECL winedmo_demuxer_stream_lang( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ) { struct demuxer_stream_lang_params params = {.demuxer = demuxer, .stream = stream}; NTSTATUS status; @@ -283,7 +273,7 @@ NTSTATUS CDECL winedmo_demuxer_stream_lang( struct winedmo_demuxer demuxer, UINT return STATUS_SUCCESS; } -NTSTATUS CDECL winedmo_demuxer_stream_name( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ) +static NTSTATUS CDECL winedmo_demuxer_stream_name( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ) { struct demuxer_stream_name_params params = {.demuxer = demuxer, .stream = stream}; NTSTATUS status; @@ -326,10 +316,44 @@ static HRESULT get_media_type( UINT code, void *params, struct media_type *media return status; } -NTSTATUS CDECL winedmo_demuxer_stream_type( struct winedmo_demuxer demuxer, UINT stream, - GUID *major, union winedmo_format **format ) +static NTSTATUS CDECL winedmo_demuxer_stream_type( struct winedmo_demuxer demuxer, UINT stream, + GUID *major, union winedmo_format **format ) { struct demuxer_stream_type_params params = {.demuxer = demuxer, .stream = stream}; TRACE( "demuxer %#I64x, stream %u, major %p, format %p\n", demuxer.handle, stream, major, format ); return get_media_type( unix_demuxer_stream_type, ¶ms, ¶ms.media_type, major, format ); } + +static const struct winedmo_demuxer_funcs winedmo_demuxer_funcs = +{ + winedmo_demuxer_create, + winedmo_demuxer_destroy, + winedmo_demuxer_read, + winedmo_demuxer_seek, + winedmo_demuxer_stream_lang, + winedmo_demuxer_stream_name, + winedmo_demuxer_stream_type, +}; + +const struct winedmo_demuxer_funcs *CDECL winedmo_get_demuxer_funcs( const char *mime_type, UINT version ) +{ + struct demuxer_check_params params = {0}; + NTSTATUS status; + + TRACE( "version %u, mime_type %s\n", version, debugstr_a(mime_type) ); + + if (version != WINEDMO_DEMUXER_VERSION) + { + ERR( "version mismatch, client wants %u but module has %u\n", version, WINEDMO_DEMUXER_VERSION ); + return NULL; + } + + lstrcpynA( params.mime_type, mime_type, sizeof(params.mime_type) ); + if ((status = UNIX_CALL( demuxer_check, ¶ms ))) + { + WARN( "unsupported mime type %s demuxer, status %#lx\n", debugstr_a(mime_type), status ); + return NULL; + } + + return &winedmo_demuxer_funcs; +} diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 90eff030dfd..81940eb6f17 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,8 +1 @@ -@ cdecl winedmo_demuxer_check(str) -@ cdecl winedmo_demuxer_create(wstr ptr int64 ptr ptr ptr ptr) -@ cdecl winedmo_demuxer_destroy(ptr) -@ cdecl winedmo_demuxer_read(int64 ptr ptr ptr) -@ cdecl winedmo_demuxer_seek(int64 int64) -@ cdecl winedmo_demuxer_stream_lang(int64 long ptr long) -@ cdecl winedmo_demuxer_stream_name(int64 long ptr long) -@ cdecl winedmo_demuxer_stream_type(int64 long ptr ptr) +@ cdecl winedmo_get_demuxer_funcs(long str ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index c068dfa1de8..2f152112a65 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -42,15 +42,20 @@ struct winedmo_stream struct winedmo_demuxer { UINT64 handle; }; -NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ); -NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream *stream, UINT64 stream_size, INT64 *duration, - UINT *stream_count, WCHAR *mime_type, struct winedmo_demuxer *demuxer ); -NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer ); -NTSTATUS CDECL winedmo_demuxer_read( struct winedmo_demuxer demuxer, UINT *stream, DMO_OUTPUT_DATA_BUFFER *buffer, UINT *buffer_size ); -NTSTATUS CDECL winedmo_demuxer_seek( struct winedmo_demuxer demuxer, INT64 timestamp ); -NTSTATUS CDECL winedmo_demuxer_stream_lang( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); -NTSTATUS CDECL winedmo_demuxer_stream_name( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); -NTSTATUS CDECL winedmo_demuxer_stream_type( struct winedmo_demuxer demuxer, UINT stream, - GUID *major, union winedmo_format **format ); +struct winedmo_demuxer_funcs +{ + NTSTATUS (*CDECL create)( const WCHAR *url, struct winedmo_stream *stream, UINT64 stream_size, INT64 *duration, + UINT *stream_count, WCHAR *mime_type, struct winedmo_demuxer *demuxer ); + NTSTATUS (*CDECL destroy)( struct winedmo_demuxer *demuxer ); + NTSTATUS (*CDECL read)( struct winedmo_demuxer demuxer, UINT *stream, DMO_OUTPUT_DATA_BUFFER *buffer, UINT *buffer_size ); + NTSTATUS (*CDECL seek)( struct winedmo_demuxer demuxer, INT64 timestamp ); + NTSTATUS (*CDECL stream_lang)( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); + NTSTATUS (*CDECL stream_name)( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); + NTSTATUS (*CDECL stream_type)( struct winedmo_demuxer demuxer, UINT stream, + GUID *major, union winedmo_format **format ); +}; +#define WINEDMO_DEMUXER_VERSION 1 /* increment when changing the demuxer API */ + +const struct winedmo_demuxer_funcs *CDECL winedmo_get_demuxer_funcs( const char *mime_type, UINT version ); #endif /* __WINE_WINEDMO_H */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9913
From: Rémi Bernon <rbernon@codeweavers.com> --- configure.ac | 59 ++++++++++++++++++++++++------------- dlls/winedmo/unix_private.h | 8 +++++ dlls/winedmo4/Makefile.in | 13 ++++++++ dlls/winedmo4/winedmo4.spec | 1 + dlls/winedmo5/Makefile.in | 13 ++++++++ dlls/winedmo5/winedmo5.spec | 1 + dlls/winedmo6/Makefile.in | 13 ++++++++ dlls/winedmo6/winedmo6.spec | 1 + dlls/winedmo7/Makefile.in | 13 ++++++++ dlls/winedmo7/winedmo7.spec | 1 + dlls/winedmo8/Makefile.in | 13 ++++++++ dlls/winedmo8/winedmo8.spec | 1 + 12 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 dlls/winedmo4/Makefile.in create mode 100644 dlls/winedmo4/winedmo4.spec create mode 100644 dlls/winedmo5/Makefile.in create mode 100644 dlls/winedmo5/winedmo5.spec create mode 100644 dlls/winedmo6/Makefile.in create mode 100644 dlls/winedmo6/winedmo6.spec create mode 100644 dlls/winedmo7/Makefile.in create mode 100644 dlls/winedmo7/winedmo7.spec create mode 100644 dlls/winedmo8/Makefile.in create mode 100644 dlls/winedmo8/winedmo8.spec diff --git a/configure.ac b/configure.ac index da4a0af4a60..2a2e119b442 100644 --- a/configure.ac +++ b/configure.ac @@ -1684,26 +1684,40 @@ 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 libavformat libavcodec],,,, - [AC_CHECK_HEADERS([libavutil/avutil.h libavformat/avformat.h libavcodec/avcodec.h libavcodec/bsf.h]) - if test "$ac_cv_header_libavutil_avutil_h" = "yes" -a "$ac_cv_header_libavformat_avformat_h" = "yes" -a "$ac_cv_header_libavcodec_avcodec_h" = "yes" - then - AC_CHECK_LIB(avutil,av_log_set_callback, - [AC_CHECK_LIB(avformat,av_find_input_format, - [AC_CHECK_LIB(avcodec,avcodec_get_name, - [AC_DEFINE(HAVE_FFMPEG, 1, [Define to 1 if you have the FFmpeg libraries.])], - [FFMPEG_LIBS=""],[$FFMPEG_LIBS])], - [FFMPEG_LIBS=""],[$FFMPEG_LIBS])], - [FFMPEG_LIBS=""],[$FFMPEG_LIBS]) - else - FFMPEG_LIBS="" - fi]) -fi -WINE_NOTICE_WITH(ffmpeg,[test "x$FFMPEG_LIBS" = x], - [FFmpeg ${notice_platform}development files not found.]) +m4_foreach([ffmpeg_version],[4,5,6,7,8,],[ + m4_define([ffmpeg_libraries],[m4_case(ffmpeg_version,[4],[libavformat libavcodec 'libavutil >= 56' 'libavutil < 57'], + [5],[libavformat libavcodec 'libavutil >= 57' 'libavutil < 58'], + [6],[libavformat libavcodec 'libavutil >= 58' 'libavutil < 59'], + [7],[libavformat libavcodec 'libavutil >= 59' 'libavutil < 60'], + [8],[libavformat libavcodec 'libavutil >= 60' 'libavutil < 61'], + [libavformat libavcodec libavutil])]) + + AS_CASE([$with_ffmpeg],m4_if(ffmpeg_version,[],[*],[ffmpeg_version[|*,]ffmpeg_version[|]ffmpeg_version[,*|*,]ffmpeg_version[,*]]),[ + ac_save_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" + PKG_CONFIG_PATH="[$FFMPEG]ffmpeg_version[_PKG_CONFIG_PATH]:$PKG_CONFIG_PATH" + + WINE_PACKAGE_FLAGS([FFMPEG]ffmpeg_version,ffmpeg_libraries,,,, + [AC_CHECK_HEADERS([libavutil/avutil.h + libavformat/avformat.h + libavcodec/avcodec.h + libavcodec/bsf.h]) + if test "$ac_cv_header_libavutil_avutil_h" = "yes" \ + -a "$ac_cv_header_libavformat_avformat_h" = "yes" \ + -a "$ac_cv_header_libavcodec_avcodec_h" = "yes" \ + ; then + AC_DEFINE([HAVE_FFMPEG]ffmpeg_version, 1, [Define to 1 if you have the FFmpeg]ffmpeg_version[ libraries.]) + else + [FFMPEG]ffmpeg_version[_LIBS]="" + fi]) + + m4_if(ffmpeg_version,[],[],WINE_TRY_CFLAGS([-Wno-deprecated-declarations],[FFMPEG]ffmpeg_version[_CFLAGS="-Wno-deprecated-declarations $FFMPEG]ffmpeg_version[_CFLAGS"])) + + WINE_NOTICE_WITH(ffmpeg,[test "x$[FFMPEG]ffmpeg_version[_LIBS]" = x], + [FFmpeg]ffmpeg_version[ ${notice_platform}development files not found.], + m4_if(ffmpeg_version,[],[],[enable_winedmo]ffmpeg_version)) + PKG_CONFIG_PATH="$ac_save_PKG_CONFIG_PATH" + ],[m4_if(ffmpeg_version,[],[],[enable_winedmo]ffmpeg_version=${[enable_winedmo]ffmpeg_version:-no})]) +]) dnl **** Check for gstreamer **** if test "x$with_gstreamer" != "xno" @@ -3362,6 +3376,11 @@ 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/winedmo4) +WINE_CONFIG_MAKEFILE(dlls/winedmo5) +WINE_CONFIG_MAKEFILE(dlls/winedmo6) +WINE_CONFIG_MAKEFILE(dlls/winedmo7) +WINE_CONFIG_MAKEFILE(dlls/winedmo8) WINE_CONFIG_MAKEFILE(dlls/winegstreamer) WINE_CONFIG_MAKEFILE(dlls/winehid.sys) WINE_CONFIG_MAKEFILE(dlls/winemac.drv) diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index 8192926bfc4..2df468f139f 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -22,6 +22,14 @@ #include <stdint.h> +#if !defined(HAVE_FFMPEG) && defined(WINEDMO_VERSION) +#if (WINEDMO_VERSION == 4 && defined(HAVE_FFMPEG4)) || (WINEDMO_VERSION == 5 && defined(HAVE_FFMPEG5)) || \ + (WINEDMO_VERSION == 6 && defined(HAVE_FFMPEG6)) || (WINEDMO_VERSION == 7 && defined(HAVE_FFMPEG7)) || \ + (WINEDMO_VERSION == 8 && defined(HAVE_FFMPEG8)) +#define HAVE_FFMPEG +#endif +#endif + #ifdef HAVE_FFMPEG #include <libavutil/avutil.h> #include <libavutil/imgutils.h> diff --git a/dlls/winedmo4/Makefile.in b/dlls/winedmo4/Makefile.in new file mode 100644 index 00000000000..2c890572d2e --- /dev/null +++ b/dlls/winedmo4/Makefile.in @@ -0,0 +1,13 @@ +MODULE = winedmo4.dll +UNIXLIB = winedmo4.so +IMPORTS = mfuuid +PARENTSRC = ../winedmo +EXTRADEFS = -DWINEDMO_VERSION=4 +UNIX_CFLAGS = $(FFMPEG4_CFLAGS) +UNIX_LIBS = $(FFMPEG4_LIBS) $(PTHREAD_LIBS) + +SOURCES = \ + main.c \ + unix_demuxer.c \ + unix_media_type.c \ + unixlib.c diff --git a/dlls/winedmo4/winedmo4.spec b/dlls/winedmo4/winedmo4.spec new file mode 100644 index 00000000000..81940eb6f17 --- /dev/null +++ b/dlls/winedmo4/winedmo4.spec @@ -0,0 +1 @@ +@ cdecl winedmo_get_demuxer_funcs(long str ptr) diff --git a/dlls/winedmo5/Makefile.in b/dlls/winedmo5/Makefile.in new file mode 100644 index 00000000000..799f27ea121 --- /dev/null +++ b/dlls/winedmo5/Makefile.in @@ -0,0 +1,13 @@ +MODULE = winedmo5.dll +UNIXLIB = winedmo5.so +IMPORTS = mfuuid +PARENTSRC = ../winedmo +EXTRADEFS = -DWINEDMO_VERSION=5 +UNIX_CFLAGS = $(FFMPEG5_CFLAGS) +UNIX_LIBS = $(FFMPEG5_LIBS) $(PTHREAD_LIBS) + +SOURCES = \ + main.c \ + unix_demuxer.c \ + unix_media_type.c \ + unixlib.c diff --git a/dlls/winedmo5/winedmo5.spec b/dlls/winedmo5/winedmo5.spec new file mode 100644 index 00000000000..81940eb6f17 --- /dev/null +++ b/dlls/winedmo5/winedmo5.spec @@ -0,0 +1 @@ +@ cdecl winedmo_get_demuxer_funcs(long str ptr) diff --git a/dlls/winedmo6/Makefile.in b/dlls/winedmo6/Makefile.in new file mode 100644 index 00000000000..4464c77cdda --- /dev/null +++ b/dlls/winedmo6/Makefile.in @@ -0,0 +1,13 @@ +MODULE = winedmo6.dll +UNIXLIB = winedmo6.so +IMPORTS = mfuuid +PARENTSRC = ../winedmo +EXTRADEFS = -DWINEDMO_VERSION=6 +UNIX_CFLAGS = $(FFMPEG6_CFLAGS) +UNIX_LIBS = $(FFMPEG6_LIBS) $(PTHREAD_LIBS) + +SOURCES = \ + main.c \ + unix_demuxer.c \ + unix_media_type.c \ + unixlib.c diff --git a/dlls/winedmo6/winedmo6.spec b/dlls/winedmo6/winedmo6.spec new file mode 100644 index 00000000000..81940eb6f17 --- /dev/null +++ b/dlls/winedmo6/winedmo6.spec @@ -0,0 +1 @@ +@ cdecl winedmo_get_demuxer_funcs(long str ptr) diff --git a/dlls/winedmo7/Makefile.in b/dlls/winedmo7/Makefile.in new file mode 100644 index 00000000000..a3da58ef3fe --- /dev/null +++ b/dlls/winedmo7/Makefile.in @@ -0,0 +1,13 @@ +MODULE = winedmo7.dll +UNIXLIB = winedmo7.so +IMPORTS = mfuuid +PARENTSRC = ../winedmo +EXTRADEFS = -DWINEDMO_VERSION=7 +UNIX_CFLAGS = $(FFMPEG7_CFLAGS) +UNIX_LIBS = $(FFMPEG7_LIBS) $(PTHREAD_LIBS) + +SOURCES = \ + main.c \ + unix_demuxer.c \ + unix_media_type.c \ + unixlib.c diff --git a/dlls/winedmo7/winedmo7.spec b/dlls/winedmo7/winedmo7.spec new file mode 100644 index 00000000000..81940eb6f17 --- /dev/null +++ b/dlls/winedmo7/winedmo7.spec @@ -0,0 +1 @@ +@ cdecl winedmo_get_demuxer_funcs(long str ptr) diff --git a/dlls/winedmo8/Makefile.in b/dlls/winedmo8/Makefile.in new file mode 100644 index 00000000000..a3ff035db1e --- /dev/null +++ b/dlls/winedmo8/Makefile.in @@ -0,0 +1,13 @@ +MODULE = winedmo8.dll +UNIXLIB = winedmo8.so +IMPORTS = mfuuid +PARENTSRC = ../winedmo +EXTRADEFS = -DWINEDMO_VERSION=8 +UNIX_CFLAGS = $(FFMPEG8_CFLAGS) +UNIX_LIBS = $(FFMPEG8_LIBS) $(PTHREAD_LIBS) + +SOURCES = \ + main.c \ + unix_demuxer.c \ + unix_media_type.c \ + unixlib.c diff --git a/dlls/winedmo8/winedmo8.spec b/dlls/winedmo8/winedmo8.spec new file mode 100644 index 00000000000..81940eb6f17 --- /dev/null +++ b/dlls/winedmo8/winedmo8.spec @@ -0,0 +1 @@ +@ cdecl winedmo_get_demuxer_funcs(long str ptr) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9913
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winedmo/main.c | 49 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 27263b64826..8c7e84e7e44 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -335,6 +335,53 @@ static const struct winedmo_demuxer_funcs winedmo_demuxer_funcs = winedmo_demuxer_stream_type, }; +#ifndef WINEDMO_VERSION + +static const WCHAR *dynamic_modules[] = +{ + L"winedmo8", + L"winedmo7", + L"winedmo6", + L"winedmo5", + L"winedmo4", +}; + +static const struct winedmo_demuxer_funcs *load_demuxer_funcs( const WCHAR *module_name, const char *mime_type, UINT version ) +{ + const struct winedmo_demuxer_funcs *(*CDECL get_funcs)( const char *, UINT ); + HMODULE module; + + if (!(module = LoadLibraryW( module_name ))) return NULL; + if (!(get_funcs = (void *)GetProcAddress( module, "winedmo_get_demuxer_funcs" ))) + { + FreeLibrary( module ); + return NULL; + } + + TRACE( "loading demuxer from %s\n", debugstr_w(module_name) ); + return get_funcs( mime_type, version ); +} + +static const struct winedmo_demuxer_funcs *get_dynamic_demuxer_funcs( const char *mime_type, UINT version ) +{ + const struct winedmo_demuxer_funcs *funcs; + + for (UINT i = 0; i < ARRAY_SIZE(dynamic_modules); i++) + if ((funcs = load_demuxer_funcs( dynamic_modules[i], mime_type, version ))) + return funcs; + + return NULL; +} + +#else + +static const struct winedmo_demuxer_funcs *get_dynamic_demuxer_funcs( const char *mime_type, UINT version ) +{ + return NULL; +} + +#endif + const struct winedmo_demuxer_funcs *CDECL winedmo_get_demuxer_funcs( const char *mime_type, UINT version ) { struct demuxer_check_params params = {0}; @@ -352,7 +399,7 @@ const struct winedmo_demuxer_funcs *CDECL winedmo_get_demuxer_funcs( const char if ((status = UNIX_CALL( demuxer_check, ¶ms ))) { WARN( "unsupported mime type %s demuxer, status %#lx\n", debugstr_a(mime_type), status ); - return NULL; + return get_dynamic_demuxer_funcs( mime_type, version ); } return &winedmo_demuxer_funcs; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9913
v2: Leave winegstreamer change aside for now, they were just a PoC of using the same interface as winedmo. Expose a versioned function table directly from the winedmo module, handle the dynamic versioned fallback in winedmo itself. Use libavutil major version alone for library version checks. The versioned FFmpeg lookup is enabled using `--with-ffmpeg=4,5,6` configure parameter, with `FFMPEG<version>_PKG_CONFIG_PATH` environment variables used to drive `pkg-config` lookup path (`pkg-config` will otherwise only take the first `.pc` file found in its path, and will fail if it doesn't match the desired ABI), while `--with-ffmpeg` alone will not build the versioned modules. The unversioned `winedmo` module is always built against the default FFmpeg libraries when found. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913#note_127793
If a distro wants to ship Wine for multiple ffmpeg versions they can ship multiple winedmo packages, using whatever mechanism the distro has to handle such things. I don't think we need to provide our own mechanism for this. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913#note_127926
I was thinking about Wine distributions like CrossOver or Proton, where they might want to ship a prebuilt FFmpeg with the patented decoders removed, while still supporting to load the system provided FFmpeg version where extra codecs would be found. The system provided FFmpeg version being unknown until execution time. Does WINEDLLPATH allow to dynamically fallback and retry other directories in the path, if a module is found in one but fails to load from there (for instance before dynamic loader doesn't find the right library version when loading the unixlib)? Then it still doesn't seem convenient to configure Wine build directories for every target version (times two if you want 32bit and 64bit), just to build the winedmo module for different FFmpeg versions. In comparison the amount of effort to achieve the same thing, as done in this MR, is much lower. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913#note_127930
Does WINEDLLPATH allow to dynamically fallback and retry other directories in the path, if a module is found in one but fails to load from there (for instance before dynamic loader doesn't find the right library version when loading the unixlib)?
Currently no, but I'm planning to add some mechanism to load a specific file as Unixlib .so instead of hardcoding it to the name and path of the corresponding PE module. This is needed for other things like the audio driver backends.
Then it still doesn't seem convenient to configure Wine build directories for every target version (times two if you want 32bit and 64bit), just to build the winedmo module for different FFmpeg versions. In comparison the amount of effort to achieve the same thing, as done in this MR, is much lower.
Given that you would need to configure and build the various ffmpeg versions first, I'm not sure that it simplifies all that much. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913#note_127953
Given that you would need to configure and build the various ffmpeg versions first, I'm not sure that it simplifies all that much.
Well I would argue that this is needed in every case, and as they would only need to build the headers and libs to build and link Wine, this can be done by disabling everything in FFmpeg, which makes the configuration and build fairly quick. On the other hand, adding some build system rules to configure Wine and build a specific module twice as many times is not so quick, and IMO an order of magnitude more painful. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913#note_127992
I don't see much difference. With ffmpeg, `configure --disable-everything`+build takes about 30 seconds here. With Wine, `configure --without-mingw; make dlls/winedmo/winedmo.so` takes 15 seconds. I fail to see how that's more painful. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913#note_127996
The thing is also that in CrossOver or Proton we touch Wine quite often, and it needs to be constantly rebuilt in case something meaningful has changed. In Proton for instance if the source of a project hasn't changed, then an iterative build is almost no-op and has almost no overhead, so FFmpeg with its every version would never need to be rebuilt, but Wine overhead would multiply. Anyway, I feel like I'm not making a convincing argument regardless, so lets forget about this for now. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913#note_128002
This merge request was closed by Rémi Bernon. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9913
participants (3)
-
Alexandre Julliard (@julliard) -
Rémi Bernon -
Rémi Bernon (@rbernon)