From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winedmo/main.c | 24 ++++++++++++++++++++- dlls/winedmo/unix_demuxer.c | 16 +++++++++++++- dlls/winedmo/unix_private.h | 5 +++++ dlls/winedmo/unixlib.c | 43 +++++++++++++++++++++++++++++++++++++ dlls/winedmo/unixlib.h | 21 ++++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index c2bdf4f89f5..9fc572082cd 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -22,17 +22,39 @@
WINE_DEFAULT_DEBUG_CHANNEL(dmo);
+ +static NTSTATUS WINAPI seek_callback( void *args, ULONG size ) +{ + struct seek_callback_params *params = args; + FIXME( "context %#I64x, offset %#I64x, stub!\n", params->context, params->offset ); + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS WINAPI read_callback( void *args, ULONG size ) +{ + struct read_callback_params *params = args; + FIXME( "context %#I64x, size %#x, stub!\n", params->context, params->size ); + return STATUS_NOT_IMPLEMENTED; +} + + 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) { + struct process_attach_params params = + { + .seek_callback = (UINT_PTR)seek_callback, + .read_callback = (UINT_PTR)read_callback, + }; NTSTATUS status; + DisableThreadLibraryCalls( instance );
status = __wine_init_unix_call(); - if (!status) status = UNIX_CALL( process_attach, NULL ); + if (!status) status = UNIX_CALL( process_attach, ¶ms ); if (status) WARN( "Failed to init unixlib, status %#lx\n", status ); }
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index bc352d96599..3a177559b5a 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -29,6 +29,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(dmo);
+static inline const char *debugstr_averr( int err ) +{ + return wine_dbg_sprintf( "%d (%s)", err, av_err2str(err) ); +} + static AVFormatContext *get_demuxer( struct winedmo_demuxer demuxer ) { return (AVFormatContext *)(UINT_PTR)demuxer.handle; @@ -58,16 +63,25 @@ NTSTATUS demuxer_create( void *arg ) { struct demuxer_create_params *params = arg; AVFormatContext *ctx; + int ret;
TRACE( "params %p\n", params );
if (!(ctx = avformat_alloc_context())) return STATUS_NO_MEMORY; - if (!(ctx->pb = avio_alloc_context( NULL, 0, 0, NULL, NULL, NULL, NULL ))) + if (!(ctx->pb = avio_alloc_context( NULL, 0, 0, NULL, unix_read_callback, NULL, unix_seek_callback ))) { avformat_free_context( ctx ); return STATUS_NO_MEMORY; }
+ if ((ret = avformat_open_input( &ctx, NULL, NULL, NULL )) < 0) + { + ERR( "Failed to open input, error %s.\n", debugstr_averr(ret) ); + avio_context_free( &ctx->pb ); + avformat_free_context( ctx ); + return STATUS_UNSUCCESSFUL; + } + params->demuxer.handle = (UINT_PTR)ctx; return STATUS_SUCCESS; } diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index d84645b835b..5517b88b3fc 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -27,6 +27,11 @@ #endif /* HAVE_FFMPEG */
#include "unixlib.h" +#include "wine/debug.h" + +/* unixlib.c */ +extern int64_t unix_seek_callback( void *opaque, int64_t offset, int whence ); +extern int unix_read_callback( void *opaque, uint8_t *buffer, int size );
/* unix_demuxer.c */ extern NTSTATUS demuxer_check( void * ); diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 6a37469a052..0ab05bd7bc2 100644 --- a/dlls/winedmo/unixlib.c +++ b/dlls/winedmo/unixlib.c @@ -29,6 +29,44 @@
WINE_DEFAULT_DEBUG_CHANNEL(dmo);
+static UINT64 seek_callback; +static UINT64 read_callback; + +int64_t unix_seek_callback( void *opaque, int64_t offset, int whence ) +{ + struct seek_callback_params params = {.dispatch = {.callback = seek_callback}, .context = (UINT_PTR)opaque}; + void *ret_ptr; + ULONG ret_len; + int status; + + TRACE( "opaque %p, offset %#jx, whence %#x\n", opaque, offset, whence ); + + params.offset = offset; + status = KeUserDispatchCallback( ¶ms.dispatch, sizeof(params), &ret_ptr, &ret_len ); + if (status || ret_len != sizeof(UINT64)) return AVERROR( EINVAL ); + offset = *(UINT64 *)ret_ptr; + + return offset; +} + +int unix_read_callback( void *opaque, uint8_t *buffer, int size ) +{ + struct read_callback_params params = {.dispatch = {.callback = read_callback}, .context = (UINT_PTR)opaque}; + int status, total; + void *ret_ptr; + ULONG ret_len; + + TRACE( "opaque %p, buffer %p, size %#x\n", opaque, buffer, size ); + + params.size = size; + status = KeUserDispatchCallback( ¶ms.dispatch, sizeof(params), &ret_ptr, &ret_len ); + if (status || ret_len != sizeof(ULONG)) return AVERROR( EINVAL ); + total = *(ULONG *)ret_ptr; + + if (!total) return AVERROR_EOF; + return total; +} + static void vlog( void *ctx, int level, const char *fmt, va_list va_args ) { enum __wine_debug_class dbcl = __WINE_DBCL_TRACE; @@ -44,6 +82,7 @@ static const char *debugstr_version( UINT version )
static NTSTATUS process_attach( void *arg ) { + struct process_attach_params *params = arg; const AVInputFormat *demuxer; void *opaque;
@@ -60,6 +99,10 @@ static NTSTATUS process_attach( void *arg ) }
av_log_set_callback( vlog ); + + seek_callback = params->seek_callback; + read_callback = params->read_callback; + return STATUS_SUCCESS; }
diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index a8a2e00dc19..4b0f533cbb4 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -26,10 +26,31 @@ #define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" +#include "ntuser.h"
#include "wine/unixlib.h" #include "wine/winedmo.h"
+struct process_attach_params +{ + UINT64 seek_callback; + UINT64 read_callback; +}; + +struct seek_callback_params +{ + struct dispatch_callback_params dispatch; + UINT64 context; + INT64 offset; +}; + +struct read_callback_params +{ + struct dispatch_callback_params dispatch; + UINT64 context; + INT32 size; +}; +
struct demuxer_check_params {