From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 4 +++- dlls/winedmo/main.c | 10 +++++++--- dlls/winedmo/unix_demuxer.c | 12 ++++++++++++ dlls/winedmo/unixlib.c | 2 ++ dlls/winedmo/unixlib.h | 1 + dlls/winedmo/winedmo.spec | 2 +- include/wine/winedmo.h | 3 ++- 7 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 11592be102a..e573e7d322a 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -90,6 +90,7 @@ struct media_source struct winedmo_demuxer winedmo_demuxer; struct winedmo_stream winedmo_stream; UINT64 file_size; + WCHAR mime_type[256];
enum { @@ -516,7 +517,8 @@ 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->winedmo_stream, &source->file_size, &source->winedmo_demuxer))) + if ((status = winedmo_demuxer_create(&source->winedmo_stream, &source->file_size, source->mime_type, + &source->winedmo_demuxer))) { WARN("Failed to create demuxer, status %#lx\n", status); hr = HRESULT_FROM_NT(status); diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 96a5027fdd8..27cfdea8620 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -17,6 +17,7 @@ */
#include "unixlib.h" +#include "winnls.h"
#include "wine/debug.h"
@@ -125,12 +126,13 @@ NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ) return status; }
-NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, struct winedmo_demuxer *demuxer ) +NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, + WCHAR *mime_type, struct winedmo_demuxer *demuxer ) { struct demuxer_create_params params = {0}; NTSTATUS status;
- TRACE( "stream %p, stream_size %I64x, demuxer %p\n", stream, *stream_size, demuxer ); + TRACE( "stream %p, stream_size %#I64x, mime_type %p, demuxer %p\n", stream, *stream_size, mime_type, demuxer );
if (!(params.context = stream_context_create( stream, stream_size ))) return STATUS_NO_MEMORY; if ((status = UNIX_CALL( demuxer_create, ¶ms ))) @@ -140,8 +142,10 @@ NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *st return status; }
+ MultiByteToWideChar( CP_ACP, 0, params.mime_type, -1, mime_type, 256 ); *demuxer = params.demuxer; - TRACE( "created demuxer %#I64x, stream %p, stream_size %#I64x\n", demuxer->handle, stream, *stream_size ); + TRACE( "created demuxer %#I64x, stream %p, stream_size %#I64x, mime_type %s\n", demuxer->handle, + stream, *stream_size, debugstr_a(params.mime_type) ); return STATUS_SUCCESS; }
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index e4e8c949d0d..c67170e0c41 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -83,6 +83,18 @@ NTSTATUS demuxer_create( void *arg ) }
params->demuxer.handle = (UINT_PTR)ctx; + if (strstr( ctx->iformat->name, "mp4" )) strcpy( params->mime_type, "video/mp4" ); + else if (strstr( ctx->iformat->name, "avi" )) strcpy( params->mime_type, "video/avi" ); + else if (strstr( ctx->iformat->name, "mpeg" )) strcpy( params->mime_type, "video/mpeg" ); + else if (strstr( ctx->iformat->name, "mp3" )) strcpy( params->mime_type, "audio/mp3" ); + else if (strstr( ctx->iformat->name, "wav" )) strcpy( params->mime_type, "audio/wav" ); + else if (strstr( ctx->iformat->name, "asf" )) strcpy( params->mime_type, "video/x-ms-asf" ); + else + { + FIXME( "Unknown MIME type for format %s\n", debugstr_a(ctx->iformat->name) ); + strcpy( params->mime_type, "video/x-application" ); + } + return STATUS_SUCCESS; }
diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 1d411f39125..7a3a83e3896 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -146,6 +146,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) { PTR32 context; struct winedmo_demuxer demuxer; + char mime_type[256]; } *params32 = arg; struct demuxer_create_params params; NTSTATUS status; @@ -153,6 +154,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) params.context = UintToPtr( params32->context ); if ((status = demuxer_create( ¶ms ))) return status; params32->demuxer = params.demuxer; + memcpy( params32->mime_type, params.mime_type, 256 );
return status; } diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index 8d39dfd5760..e452ed5be1c 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -72,6 +72,7 @@ struct demuxer_create_params { struct stream_context *context; struct winedmo_demuxer demuxer; + char mime_type[256]; };
struct demuxer_destroy_params diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index ef718289f9d..0b848f8be16 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,3 +1,3 @@ @ cdecl winedmo_demuxer_check(str) -@ cdecl winedmo_demuxer_create(ptr ptr ptr) +@ cdecl winedmo_demuxer_create(ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index 07192242a2a..c91b2cc51c2 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -35,7 +35,8 @@ struct winedmo_stream struct winedmo_demuxer { UINT64 handle; };
NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ); -NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, struct winedmo_demuxer *demuxer ); +NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, + WCHAR *mime_type, struct winedmo_demuxer *demuxer ); NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer );
#endif /* __WINE_WINEDMO_H */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 4 ++-- dlls/winedmo/main.c | 22 +++++++++++++++++----- dlls/winedmo/unix_demuxer.c | 12 +++++++++--- dlls/winedmo/unixlib.c | 2 ++ dlls/winedmo/unixlib.h | 1 + dlls/winedmo/winedmo.spec | 2 +- include/wine/winedmo.h | 2 +- 7 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index e573e7d322a..79255074498 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -517,8 +517,8 @@ 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->winedmo_stream, &source->file_size, source->mime_type, - &source->winedmo_demuxer))) + if ((status = winedmo_demuxer_create(source->url, &source->winedmo_stream, &source->file_size, + source->mime_type, &source->winedmo_demuxer))) { WARN("Failed to create demuxer, status %#lx\n", status); hr = HRESULT_FROM_NT(status); diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 27cfdea8620..87ea214337e 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -126,16 +126,28 @@ NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ) return status; }
-NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, +NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream *stream, UINT64 *stream_size, WCHAR *mime_type, struct winedmo_demuxer *demuxer ) { struct demuxer_create_params params = {0}; + char *tmp = NULL; NTSTATUS status; + UINT len;
- TRACE( "stream %p, stream_size %#I64x, mime_type %p, demuxer %p\n", stream, *stream_size, mime_type, demuxer ); + TRACE( "url %s, stream %p, stream_size %#I64x, mime_type %p, demuxer %p\n", debugstr_w(url), + stream, *stream_size, mime_type, demuxer );
if (!(params.context = stream_context_create( stream, stream_size ))) return STATUS_NO_MEMORY; - if ((status = UNIX_CALL( demuxer_create, ¶ms ))) + + if (url && (len = WideCharToMultiByte( CP_ACP, 0, url, -1, NULL, 0, NULL, NULL )) && (tmp = malloc( len ))) + { + WideCharToMultiByte( CP_ACP, 0, url, -1, tmp, len, NULL, NULL ); + params.url = tmp; + } + status = UNIX_CALL( demuxer_create, ¶ms ); + free( tmp ); + + if (status) { WARN( "demuxer_create failed, status %#lx\n", status ); stream_context_destroy( params.context ); @@ -144,8 +156,8 @@ NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *st
MultiByteToWideChar( CP_ACP, 0, params.mime_type, -1, mime_type, 256 ); *demuxer = params.demuxer; - TRACE( "created demuxer %#I64x, stream %p, stream_size %#I64x, mime_type %s\n", demuxer->handle, - stream, *stream_size, debugstr_a(params.mime_type) ); + TRACE( "created demuxer %#I64x, url %s, stream %p, stream_size %#I64x, mime_type %s\n", demuxer->handle, + debugstr_w(url), stream, *stream_size, debugstr_a(params.mime_type) ); return STATUS_SUCCESS; }
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index c67170e0c41..4ddd25630e0 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -62,10 +62,11 @@ NTSTATUS demuxer_check( void *arg ) NTSTATUS demuxer_create( void *arg ) { struct demuxer_create_params *params = arg; + const char *ext = params->url ? strrchr( params->url, '.' ) : ""; AVFormatContext *ctx; int ret;
- TRACE( "context %p\n", params->context ); + TRACE( "context %p, url %s, mime %s\n", params->context, debugstr_a(params->url), debugstr_a(params->mime_type) );
if (!(ctx = avformat_alloc_context())) return STATUS_NO_MEMORY; if (!(ctx->pb = avio_alloc_context( NULL, 0, 0, params->context, unix_read_callback, NULL, unix_seek_callback ))) @@ -88,10 +89,15 @@ NTSTATUS demuxer_create( void *arg ) else if (strstr( ctx->iformat->name, "mpeg" )) strcpy( params->mime_type, "video/mpeg" ); else if (strstr( ctx->iformat->name, "mp3" )) strcpy( params->mime_type, "audio/mp3" ); else if (strstr( ctx->iformat->name, "wav" )) strcpy( params->mime_type, "audio/wav" ); - else if (strstr( ctx->iformat->name, "asf" )) strcpy( params->mime_type, "video/x-ms-asf" ); + else if (strstr( ctx->iformat->name, "asf" )) + { + if (!strcmp( ext, ".wma" )) strcpy( params->mime_type, "audio/x-ms-wma" ); + else if (!strcmp( ext, ".wmv" )) strcpy( params->mime_type, "video/x-ms-wmv" ); + else strcpy( params->mime_type, "video/x-ms-asf" ); + } else { - FIXME( "Unknown MIME type for format %s\n", debugstr_a(ctx->iformat->name) ); + FIXME( "Unknown MIME type for format %s, url %s\n", debugstr_a(ctx->iformat->name), debugstr_a(params->url) ); strcpy( params->mime_type, "video/x-application" ); }
diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 7a3a83e3896..acddf489410 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -144,6 +144,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) { struct { + PTR32 url; PTR32 context; struct winedmo_demuxer demuxer; char mime_type[256]; @@ -151,6 +152,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) struct demuxer_create_params params; NTSTATUS status;
+ params.url = UintToPtr( params32->url ); params.context = UintToPtr( params32->context ); if ((status = demuxer_create( ¶ms ))) return status; params32->demuxer = params.demuxer; diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index e452ed5be1c..31c8ed69763 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -70,6 +70,7 @@ struct demuxer_check_params
struct demuxer_create_params { + const char *url; struct stream_context *context; struct winedmo_demuxer demuxer; char mime_type[256]; diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 0b848f8be16..610fcb69144 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,3 +1,3 @@ @ cdecl winedmo_demuxer_check(str) -@ cdecl winedmo_demuxer_create(ptr ptr ptr ptr) +@ cdecl winedmo_demuxer_create(wstr ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index c91b2cc51c2..34f031e8f73 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -35,7 +35,7 @@ struct winedmo_stream struct winedmo_demuxer { UINT64 handle; };
NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ); -NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, +NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream *stream, UINT64 *stream_size, WCHAR *mime_type, struct winedmo_demuxer *demuxer ); NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 3 ++- dlls/winedmo/main.c | 7 ++++--- dlls/winedmo/unix_demuxer.c | 9 +++++++++ dlls/winedmo/unixlib.c | 2 ++ dlls/winedmo/unixlib.h | 1 + dlls/winedmo/winedmo.spec | 2 +- include/wine/winedmo.h | 2 +- 7 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 79255074498..ba3209637bd 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -90,6 +90,7 @@ struct media_source struct winedmo_demuxer winedmo_demuxer; struct winedmo_stream winedmo_stream; UINT64 file_size; + UINT stream_count; WCHAR mime_type[256];
enum @@ -518,7 +519,7 @@ static HRESULT media_source_async_create(struct media_source *source, IMFAsyncRe source->winedmo_stream.p_read = media_source_read_cb;
if ((status = winedmo_demuxer_create(source->url, &source->winedmo_stream, &source->file_size, - source->mime_type, &source->winedmo_demuxer))) + &source->stream_count, source->mime_type, &source->winedmo_demuxer))) { WARN("Failed to create demuxer, status %#lx\n", status); hr = HRESULT_FROM_NT(status); diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 87ea214337e..22b6220ad05 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -127,7 +127,7 @@ NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ) }
NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream *stream, UINT64 *stream_size, - WCHAR *mime_type, struct winedmo_demuxer *demuxer ) + UINT *stream_count, WCHAR *mime_type, struct winedmo_demuxer *demuxer ) { struct demuxer_create_params params = {0}; char *tmp = NULL; @@ -154,10 +154,11 @@ NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream * return status; }
+ *stream_count = params.stream_count; MultiByteToWideChar( CP_ACP, 0, params.mime_type, -1, mime_type, 256 ); *demuxer = params.demuxer; - TRACE( "created demuxer %#I64x, url %s, stream %p, stream_size %#I64x, mime_type %s\n", demuxer->handle, - debugstr_w(url), stream, *stream_size, debugstr_a(params.mime_type) ); + TRACE( "created demuxer %#I64x, stream %p, stream_size %#I64x, stream_count %u, mime_type %s\n", demuxer->handle, + stream, *stream_size, params.stream_count, debugstr_a(params.mime_type) ); return STATUS_SUCCESS; }
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 4ddd25630e0..8c0dcf09e12 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -83,7 +83,16 @@ NTSTATUS demuxer_create( void *arg ) return STATUS_UNSUCCESSFUL; }
+ if (!(ctx->nb_streams && ctx->duration != AV_NOPTS_VALUE) && (ret = avformat_find_stream_info( ctx, NULL )) < 0) + { + ERR( "Failed to find stream info, ret %d (%s).\n", ret, av_err2str(ret) ); + avio_context_free( &ctx->pb ); + avformat_free_context( ctx ); + return STATUS_UNSUCCESSFUL; + } + params->demuxer.handle = (UINT_PTR)ctx; + params->stream_count = ctx->nb_streams; if (strstr( ctx->iformat->name, "mp4" )) strcpy( params->mime_type, "video/mp4" ); else if (strstr( ctx->iformat->name, "avi" )) strcpy( params->mime_type, "video/avi" ); else if (strstr( ctx->iformat->name, "mpeg" )) strcpy( params->mime_type, "video/mpeg" ); diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index acddf489410..3f1a2c1c440 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -148,6 +148,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) PTR32 context; struct winedmo_demuxer demuxer; char mime_type[256]; + UINT32 stream_count; } *params32 = arg; struct demuxer_create_params params; NTSTATUS status; @@ -157,6 +158,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) if ((status = demuxer_create( ¶ms ))) return status; params32->demuxer = params.demuxer; memcpy( params32->mime_type, params.mime_type, 256 ); + params32->stream_count = params.stream_count;
return status; } diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index 31c8ed69763..ad0dacf7016 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -74,6 +74,7 @@ struct demuxer_create_params struct stream_context *context; struct winedmo_demuxer demuxer; char mime_type[256]; + UINT32 stream_count; };
struct demuxer_destroy_params diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 610fcb69144..60dca7e5405 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,3 +1,3 @@ @ cdecl winedmo_demuxer_check(str) -@ cdecl winedmo_demuxer_create(wstr ptr ptr ptr ptr) +@ cdecl winedmo_demuxer_create(wstr ptr ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index 34f031e8f73..37cf43a2301 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -36,7 +36,7 @@ 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, - WCHAR *mime_type, struct winedmo_demuxer *demuxer ); + UINT *stream_count, WCHAR *mime_type, struct winedmo_demuxer *demuxer ); NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer );
#endif /* __WINE_WINEDMO_H */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 3 ++- dlls/winedmo/main.c | 7 +++--- dlls/winedmo/unix_demuxer.c | 42 +++++++++++++++++++++++++++++++----- dlls/winedmo/unixlib.c | 2 ++ dlls/winedmo/unixlib.h | 1 + dlls/winedmo/winedmo.spec | 2 +- include/wine/winedmo.h | 2 +- 7 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index ba3209637bd..02034d512d8 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -90,6 +90,7 @@ struct media_source struct winedmo_demuxer winedmo_demuxer; struct winedmo_stream winedmo_stream; UINT64 file_size; + INT64 duration; UINT stream_count; WCHAR mime_type[256];
@@ -518,7 +519,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, + if ((status = winedmo_demuxer_create(source->url, &source->winedmo_stream, &source->file_size, &source->duration, &source->stream_count, source->mime_type, &source->winedmo_demuxer))) { WARN("Failed to create demuxer, status %#lx\n", status); diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 22b6220ad05..ad7bc6753cd 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -126,7 +126,7 @@ NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ) return status; }
-NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream *stream, UINT64 *stream_size, +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}; @@ -154,11 +154,12 @@ NTSTATUS CDECL winedmo_demuxer_create( const WCHAR *url, struct winedmo_stream * return status; }
+ *duration = params.duration; *stream_count = params.stream_count; MultiByteToWideChar( CP_ACP, 0, params.mime_type, -1, mime_type, 256 ); *demuxer = params.demuxer; - TRACE( "created demuxer %#I64x, stream %p, stream_size %#I64x, stream_count %u, mime_type %s\n", demuxer->handle, - stream, *stream_size, params.stream_count, debugstr_a(params.mime_type) ); + TRACE( "created demuxer %#I64x, stream %p, stream_size %#I64x, duration %I64d, stream_count %u, mime_type %s\n", + demuxer->handle, stream, *stream_size, params.duration, params.stream_count, debugstr_a(params.mime_type) ); return STATUS_SUCCESS; }
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 8c0dcf09e12..2a3499068dc 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -39,6 +39,34 @@ static AVFormatContext *get_demuxer( struct winedmo_demuxer demuxer ) return (AVFormatContext *)(UINT_PTR)demuxer.handle; }
+static INT64 get_user_time( INT64 time, AVRational time_base ) +{ + static const AVRational USER_TIME_BASE_Q = {1, 10000000}; + return av_rescale_q_rnd( time, time_base, USER_TIME_BASE_Q, AV_ROUND_PASS_MINMAX ); +} + +static INT64 get_stream_time( const AVStream *stream, INT64 time ) +{ + if (stream->time_base.num && stream->time_base.den) return get_user_time( time, stream->time_base ); + return get_user_time( time, AV_TIME_BASE_Q ); +} + +static INT64 get_context_duration( const AVFormatContext *ctx ) +{ + INT64 i, max_duration = AV_NOPTS_VALUE; + + for (i = 0; i < ctx->nb_streams; i++) + { + const AVStream *stream = ctx->streams[i]; + INT64 duration = get_stream_time( stream, stream->duration ); + if (duration == AV_NOPTS_VALUE) continue; + if (duration >= max_duration) max_duration = duration; + if (max_duration == AV_NOPTS_VALUE) max_duration = duration; + } + + return max_duration; +} + NTSTATUS demuxer_check( void *arg ) { struct demuxer_check_params *params = arg; @@ -83,12 +111,16 @@ NTSTATUS demuxer_create( void *arg ) return STATUS_UNSUCCESSFUL; }
- if (!(ctx->nb_streams && ctx->duration != AV_NOPTS_VALUE) && (ret = avformat_find_stream_info( ctx, NULL )) < 0) + if ((params->duration = get_context_duration( ctx )) == AV_NOPTS_VALUE) { - ERR( "Failed to find stream info, ret %d (%s).\n", ret, av_err2str(ret) ); - avio_context_free( &ctx->pb ); - avformat_free_context( ctx ); - return STATUS_UNSUCCESSFUL; + if ((ret = avformat_find_stream_info( ctx, NULL )) < 0) + { + ERR( "Failed to find stream info, ret %d (%s).\n", ret, av_err2str(ret) ); + avio_context_free( &ctx->pb ); + avformat_free_context( ctx ); + return STATUS_UNSUCCESSFUL; + } + params->duration = get_context_duration( ctx ); }
params->demuxer.handle = (UINT_PTR)ctx; diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 3f1a2c1c440..e6f2a8ee889 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -149,6 +149,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) struct winedmo_demuxer demuxer; char mime_type[256]; UINT32 stream_count; + INT64 duration; } *params32 = arg; struct demuxer_create_params params; NTSTATUS status; @@ -159,6 +160,7 @@ static NTSTATUS wow64_demuxer_create( void *arg ) params32->demuxer = params.demuxer; memcpy( params32->mime_type, params.mime_type, 256 ); params32->stream_count = params.stream_count; + params32->duration = params.duration;
return status; } diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index ad0dacf7016..b3f0583ff07 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -75,6 +75,7 @@ struct demuxer_create_params struct winedmo_demuxer demuxer; char mime_type[256]; UINT32 stream_count; + INT64 duration; };
struct demuxer_destroy_params diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 60dca7e5405..61da0617a7c 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,3 +1,3 @@ @ cdecl winedmo_demuxer_check(str) -@ cdecl winedmo_demuxer_create(wstr ptr ptr ptr ptr ptr) +@ cdecl winedmo_demuxer_create(wstr ptr ptr ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index 37cf43a2301..758066a85b5 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -35,7 +35,7 @@ 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, +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 );
From: Rémi Bernon rbernon@codeweavers.com
--- configure.ac | 8 ++-- dlls/winedmo/Makefile.in | 1 + dlls/winedmo/main.c | 32 ++++++++++++++ dlls/winedmo/unix_demuxer.c | 12 +++++ dlls/winedmo/unix_media_type.c | 80 ++++++++++++++++++++++++++++++++++ dlls/winedmo/unix_private.h | 9 ++++ dlls/winedmo/unixlib.c | 2 + dlls/winedmo/unixlib.h | 22 ++++++++++ dlls/winedmo/winedmo.spec | 1 + include/wine/winedmo.h | 10 +++++ 10 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 dlls/winedmo/unix_media_type.c
diff --git a/configure.ac b/configure.ac index bd7c0e14718..eed177ba861 100644 --- a/configure.ac +++ b/configure.ac @@ -1622,14 +1622,16 @@ WINE_NOTICE_WITH(pulse, [test -z "$PULSE_LIBS"], dnl **** Check for FFmpeg **** if test "x$with_ffmpeg" != "xno"; then - WINE_PACKAGE_FLAGS(FFMPEG,[libavutil libavformat],,,, - [AC_CHECK_HEADERS([libavutil/avutil.h libavformat/avformat.h]) - if test "$ac_cv_header_libavutil_avutil_h" = "yes" -a "$ac_cv_header_libavformat_avformat_h" = "yes" + WINE_PACKAGE_FLAGS(FFMPEG,[libavutil libavformat libavcodec],,,, + [AC_CHECK_HEADERS([libavutil/avutil.h libavformat/avformat.h libavcodec/avcodec.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="" diff --git a/dlls/winedmo/Makefile.in b/dlls/winedmo/Makefile.in index 5b816357770..2d829deb07b 100644 --- a/dlls/winedmo/Makefile.in +++ b/dlls/winedmo/Makefile.in @@ -7,4 +7,5 @@ UNIX_LIBS = $(FFMPEG_LIBS) $(PTHREAD_LIBS) SOURCES = \ main.c \ unix_demuxer.c \ + unix_media_type.c \ unixlib.c diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index ad7bc6753cd..7d30c31d05d 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -179,3 +179,35 @@ NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer )
return status; } + +static HRESULT get_media_type( UINT code, void *params, struct media_type *media_type, + GUID *major, union winedmo_format **format ) +{ + NTSTATUS status; + + media_type->format = NULL; + if ((status = WINE_UNIX_CALL( code, params )) && status == STATUS_BUFFER_TOO_SMALL) + { + if (!(media_type->format = malloc( media_type->format_size ))) return STATUS_NO_MEMORY; + status = WINE_UNIX_CALL( code, params ); + } + + if (!status) + { + *major = media_type->major; + *format = media_type->format; + return STATUS_SUCCESS; + } + + WARN( "Failed to get media type, code %#x, status %#lx\n", code, status ); + free( media_type->format ); + return status; +} + +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 ); +} diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 2a3499068dc..632b75480d7 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -159,4 +159,16 @@ NTSTATUS demuxer_destroy( void *arg ) return STATUS_SUCCESS; }
+NTSTATUS demuxer_stream_type( void *arg ) +{ + struct demuxer_stream_type_params *params = arg; + AVFormatContext *ctx = get_demuxer( params->demuxer ); + AVStream *stream = ctx->streams[params->stream]; + + TRACE( "context %p, stream %u, stream %p, index %u\n", ctx, params->stream, stream, stream->index ); + + return media_type_from_codec_params( stream->codecpar, &stream->sample_aspect_ratio, + &stream->avg_frame_rate, 0, ¶ms->media_type ); +} + #endif /* HAVE_FFMPEG */ diff --git a/dlls/winedmo/unix_media_type.c b/dlls/winedmo/unix_media_type.c new file mode 100644 index 00000000000..fb0350d39b4 --- /dev/null +++ b/dlls/winedmo/unix_media_type.c @@ -0,0 +1,80 @@ +/* + * 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 "initguid.h" +#include "unix_private.h" + +#include "d3d9.h" +#include "mfapi.h" +#include "uuids.h" + +#include "wine/debug.h" + +#ifdef HAVE_FFMPEG + +WINE_DEFAULT_DEBUG_CHANNEL(dmo); + +#define TRACE_HEXDUMP( data, size ) \ + if (__WINE_IS_DEBUG_ON(_TRACE, __wine_dbch___default)) \ + do { \ + const unsigned char *__ptr, *__end, *__tmp; \ + for (__ptr = (void *)(data), __end = __ptr + (size); __ptr < __end; __ptr += 16) \ + { \ + char __buf[256], *__lim = __buf + sizeof(__buf), *__out = __buf; \ + __out += snprintf( __out, __lim - __out, "%08zx ", (char *)__ptr - (char *)data ); \ + for (__tmp = __ptr; __tmp < __end && __tmp < __ptr + 16; ++__tmp) \ + __out += snprintf( __out, __lim - __out, " %02x", *__tmp ); \ + memset( __out, ' ', (__ptr + 16 - __tmp) * 3 + 2 ); \ + __out += (__ptr + 16 - __tmp) * 3 + 2; \ + for (__tmp = __ptr; __tmp < __end && __tmp < __ptr + 16; ++__tmp) \ + *__out++ = *__tmp >= ' ' && *__tmp <= '~' ? *__tmp : '.'; \ + *__out++ = 0; \ + TRACE( "%s\n", __buf ); \ + } \ + } while (0) + +NTSTATUS media_type_from_codec_params( const AVCodecParameters *params, const AVRational *sar, const AVRational *fps, + UINT32 align, struct media_type *media_type ) +{ + TRACE( "codec type %#x, id %#x (%s), tag %#x (%s)\n", params->codec_type, params->codec_id, avcodec_get_name(params->codec_id), + params->codec_tag, debugstr_fourcc(params->codec_tag) ); + if (params->extradata_size) TRACE_HEXDUMP( params->extradata, params->extradata_size ); + + if (params->codec_type == AVMEDIA_TYPE_AUDIO) + { + media_type->major = MFMediaType_Audio; + return STATUS_SUCCESS; + } + + if (params->codec_type == AVMEDIA_TYPE_VIDEO) + { + media_type->major = MFMediaType_Video; + return STATUS_SUCCESS; + } + + FIXME( "Unknown type %#x\n", params->codec_type ); + return STATUS_NOT_IMPLEMENTED; +} + +#endif /* HAVE_FFMPEG */ diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index 41607ae1e3c..bb91e06449b 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -26,6 +26,10 @@ #include <libavutil/avutil.h> #include <libavutil/imgutils.h> #include <libavformat/avformat.h> +#include <libavcodec/avcodec.h> +#else +typedef struct AVCodecParameters AVCodecParameters; +typedef struct AVRational AVRational; #endif /* HAVE_FFMPEG */
#include "unixlib.h" @@ -39,3 +43,8 @@ extern int unix_read_callback( void *opaque, uint8_t *buffer, int size ); extern NTSTATUS demuxer_check( void * ); extern NTSTATUS demuxer_create( void * ); extern NTSTATUS demuxer_destroy( void * ); +extern NTSTATUS demuxer_stream_type( void * ); + +/* unix_media_type.c */ +extern NTSTATUS media_type_from_codec_params( const AVCodecParameters *params, const AVRational *sar, const AVRational *fps, + UINT32 align, struct media_type *media_type ); diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index e6f2a8ee889..13178ec5260 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -132,6 +132,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = X( demuxer_check ), X( demuxer_create ), X( demuxer_destroy ), + X( demuxer_stream_type ), };
C_ASSERT(ARRAY_SIZE(__wine_unix_call_funcs) == unix_funcs_count); @@ -190,6 +191,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = X( demuxer_check ), X64( demuxer_create ), X64( demuxer_destroy ), + X( demuxer_stream_type ), };
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 b3f0583ff07..9e1bdd14ad2 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -63,6 +63,20 @@ struct read_callback_params };
+struct media_type +{ + GUID major; + UINT32 format_size; + union + { + void *format; + WAVEFORMATEX *audio; + MFVIDEOFORMAT *video; + UINT64 __pad; + }; +}; + + struct demuxer_check_params { char mime_type[256]; @@ -84,6 +98,13 @@ struct demuxer_destroy_params struct stream_context *context; };
+struct demuxer_stream_type_params +{ + struct winedmo_demuxer demuxer; + UINT32 stream; + struct media_type media_type; +}; +
enum unix_funcs { @@ -92,6 +113,7 @@ enum unix_funcs unix_demuxer_check, unix_demuxer_create, unix_demuxer_destroy, + unix_demuxer_stream_type,
unix_funcs_count, }; diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 61da0617a7c..8038312d942 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,3 +1,4 @@ @ cdecl winedmo_demuxer_check(str) @ cdecl winedmo_demuxer_create(wstr ptr ptr ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) +@ cdecl winedmo_demuxer_stream_type(int64 ptr ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index 758066a85b5..cdcd77f5dd0 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -26,6 +26,14 @@ #include "winbase.h" #include "winternl.h"
+#include "mfapi.h" + +union winedmo_format +{ + WAVEFORMATEX audio; + MFVIDEOFORMAT video; +}; + struct winedmo_stream { NTSTATUS (CDECL *p_seek)( struct winedmo_stream *stream, UINT64 *pos ); @@ -38,5 +46,7 @@ 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_stream_type( struct winedmo_demuxer demuxer, UINT stream, + GUID *major, union winedmo_format **format );
#endif /* __WINE_WINEDMO_H */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 81 +++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 02034d512d8..a4cc2a92c31 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -94,6 +94,8 @@ struct media_source UINT stream_count; WCHAR mime_type[256];
+ UINT *stream_map; + enum { SOURCE_STOPPED, @@ -342,6 +344,7 @@ static ULONG WINAPI media_source_Release(IMFMediaSource *iface) IMFMediaSource_Shutdown(iface);
winedmo_demuxer_destroy(&source->winedmo_demuxer); + free(source->stream_map);
IMFMediaEventQueue_Release(source->queue); IMFByteStream_Release(source->stream); @@ -477,7 +480,73 @@ static const IMFMediaSourceVtbl media_source_vtbl = media_source_Shutdown, };
-static NTSTATUS CDECL media_source_seek_cb(struct winedmo_stream *stream, UINT64 *pos) +static HRESULT get_stream_media_type(struct winedmo_demuxer demuxer, UINT index, GUID *major) +{ + union winedmo_format *format; + NTSTATUS status; + + TRACE("demuxer %p, index %u\n", &demuxer, index); + + if ((status = winedmo_demuxer_stream_type(demuxer, index, major, &format))) + { + WARN("Failed to get stream %u type, status %#lx\n", index, status); + return HRESULT_FROM_NT(status); + } + + free(format); + return S_OK; +} + +static void media_source_init_stream_map(struct media_source *source, UINT stream_count) +{ + int i, n = 0; + GUID major; + + TRACE("source %p, stream_count %d\n", source, stream_count); + + if (wcscmp(source->mime_type, L"video/mp4")) + { + for (i = stream_count - 1; i >= 0; i--) + { + TRACE("mapping source %p stream %u to demuxer stream %u\n", source, i, i); + source->stream_map[i] = i; + } + return; + } + + for (i = stream_count - 1; i >= 0; i--) + { + if (FAILED(get_stream_media_type(source->winedmo_demuxer, i, &major))) + continue; + if (IsEqualGUID(&major, &MFMediaType_Audio)) + { + TRACE("mapping source %p stream %u to demuxer stream %u\n", source, n, i); + source->stream_map[n++] = i; + } + } + for (i = stream_count - 1; i >= 0; i--) + { + if (FAILED(get_stream_media_type(source->winedmo_demuxer, i, &major))) + continue; + if (IsEqualGUID(&major, &MFMediaType_Video)) + { + TRACE("mapping source %p stream %u to demuxer stream %u\n", source, n, i); + source->stream_map[n++] = i; + } + } + for (i = stream_count - 1; i >= 0; i--) + { + if (FAILED(get_stream_media_type(source->winedmo_demuxer, i, &major))) + continue; + if (!IsEqualGUID(&major, &MFMediaType_Audio) && !IsEqualGUID(&major, &MFMediaType_Video)) + { + TRACE("mapping source %p stream %u to demuxer stream %u\n", source, n, i); + source->stream_map[n++] = i; + } + } +} + +static NTSTATUS CDECL media_source_seek_cb( struct winedmo_stream *stream, UINT64 *pos ) { struct media_source *source = CONTAINING_RECORD(stream, struct media_source, winedmo_stream); TRACE("stream %p, pos %p\n", stream, pos); @@ -524,8 +593,18 @@ static HRESULT media_source_async_create(struct media_source *source, IMFAsyncRe { WARN("Failed to create demuxer, status %#lx\n", status); hr = HRESULT_FROM_NT(status); + goto done; }
+ if (!(source->stream_map = calloc(source->stream_count, sizeof(*source->stream_map)))) + { + hr = E_OUTOFMEMORY; + goto done; + } + + media_source_init_stream_map(source, source->stream_count); + +done: IMFAsyncResult_SetStatus(result, hr); return MFInvokeCallback((IMFAsyncResult *)state); }
Hi with this commit ffmpeg implementation can decode wmv-wma and asf ?
On Fri Sep 13 13:53:36 2024 +0000, Carlos Rodriguez wrote:
Hi with this commit ffmpeg implementation can decode wmv-wma and asf ?
No, it still misses a lot of things and isn't usable for the moment.
On Fri Sep 13 13:53:36 2024 +0000, Rémi Bernon wrote:
No, it still misses a lot of things and isn't usable for the moment.
in actual state ffmpeg implementation can decode, ask before stay testing some titles like silent hill 3 (avi cinematic) and work ok but wine git stay using ffmpeg or gstreamer?
and i use this on wine register:
DisableGstByteStreamHandler = 1
in the HKCU\Software\Wine\MediaFoundation registry key.
like appear on this:
https://gitlab.winehq.org/wine/wine/-/merge_requests/6442
thanks
No, it still misses a lot of things and isn't usable for the moment.
Is it worth throwing a `WARN` until you think it's (at least partially) usable? You know something to stop us eager people repeatedly asking silly questions ;-)