From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 26 +++++++++++++++++- dlls/winedmo/main.c | 53 +++++++++++++++++++++++++++++------- dlls/winedmo/unixlib.h | 1 + dlls/winedmo/winedmo.spec | 2 +- include/wine/winedmo.h | 8 +++++- 5 files changed, 77 insertions(+), 13 deletions(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 9315b1bc06b..11592be102a 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -88,6 +88,7 @@ struct media_source float rate;
struct winedmo_demuxer winedmo_demuxer; + struct winedmo_stream winedmo_stream; UINT64 file_size;
enum @@ -473,6 +474,26 @@ static const IMFMediaSourceVtbl media_source_vtbl = media_source_Shutdown, };
+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); + + if (FAILED(IMFByteStream_Seek(source->stream, msoBegin, *pos, 0, pos))) + return STATUS_UNSUCCESSFUL; + return STATUS_SUCCESS; +} + +static NTSTATUS CDECL media_source_read_cb(struct winedmo_stream *stream, BYTE *buffer, ULONG *size) +{ + struct media_source *source = CONTAINING_RECORD(stream, struct media_source, winedmo_stream); + TRACE("stream %p, buffer %p, size %p\n", stream, buffer, size); + + if (FAILED(IMFByteStream_Read(source->stream, buffer, *size, size))) + return STATUS_UNSUCCESSFUL; + return STATUS_SUCCESS; +} + static HRESULT media_source_async_create(struct media_source *source, IMFAsyncResult *result) { IUnknown *state = IMFAsyncResult_GetStateNoAddRef(result); @@ -492,7 +513,10 @@ static HRESULT media_source_async_create(struct media_source *source, IMFAsyncRe hr = S_OK; }
- if ((status = winedmo_demuxer_create(&source->winedmo_demuxer))) + 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))) { 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 9de56e64902..96a5027fdd8 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -23,12 +23,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(dmo);
-static struct stream_context *stream_context_create(void) +static struct stream_context *stream_context_create( struct winedmo_stream *stream, UINT64 *stream_size ) { struct stream_context *context;
if (!(context = malloc( 0x10000 ))) return NULL; - context->length = 0; + context->stream = (UINT_PTR)stream; + context->length = *stream_size; context->position = 0; context->buffer_size = 0x10000 - offsetof(struct stream_context, buffer);
@@ -41,18 +42,50 @@ static void stream_context_destroy( struct stream_context *context ) }
+static struct stream_context *get_stream_context( UINT64 handle ) +{ + return (struct stream_context *)(UINT_PTR)handle; +} + +static struct winedmo_stream *get_stream( UINT64 handle ) +{ + return (struct winedmo_stream *)(UINT_PTR)handle; +} + 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; + struct stream_context *context = get_stream_context( params->context ); + struct winedmo_stream *stream = get_stream( context->stream ); + NTSTATUS status = STATUS_NOT_IMPLEMENTED; + UINT64 pos = params->offset; + + TRACE( "stream %p, offset %#I64x\n", stream, params->offset ); + + if (!stream->p_seek || (status = stream->p_seek( stream, &pos ))) + WARN( "Failed to seek stream %p, status %#lx\n", stream, status ); + else + TRACE( "Seeked stream %p to %#I64x\n", stream, pos ); + + return NtCallbackReturn( &pos, sizeof(pos), status ); }
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; + struct stream_context *context = get_stream_context( params->context ); + struct winedmo_stream *stream = get_stream( context->stream ); + NTSTATUS status = STATUS_NOT_IMPLEMENTED; + ULONG ret = params->size; + + TRACE( "stream %p, size %#x\n", stream, params->size ); + + if (!stream->p_read || (status = stream->p_read( stream, context->buffer, &ret ))) + WARN( "Failed to read from stream %p, status %#lx\n", stream, status ); + else + TRACE( "Read %#lx bytes from stream %p\n", ret, stream ); + + return NtCallbackReturn( &ret, sizeof(ret), status ); }
@@ -92,14 +125,14 @@ NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ) return status; }
-NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_demuxer *demuxer ) +NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, struct winedmo_demuxer *demuxer ) { struct demuxer_create_params params = {0}; NTSTATUS status;
- TRACE( "demuxer %p\n", demuxer ); + TRACE( "stream %p, stream_size %I64x, demuxer %p\n", stream, *stream_size, demuxer );
- if (!(params.context = stream_context_create())) return STATUS_NO_MEMORY; + if (!(params.context = stream_context_create( stream, stream_size ))) return STATUS_NO_MEMORY; if ((status = UNIX_CALL( demuxer_create, ¶ms ))) { WARN( "demuxer_create failed, status %#lx\n", status ); @@ -108,7 +141,7 @@ NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_demuxer *demuxer ) }
*demuxer = params.demuxer; - TRACE( "created %#I64x\n", demuxer->handle ); + TRACE( "created demuxer %#I64x, stream %p, stream_size %#I64x\n", demuxer->handle, stream, *stream_size ); return STATUS_SUCCESS; }
diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index 5aa4cc42ba2..8d39dfd5760 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -39,6 +39,7 @@ struct process_attach_params
struct stream_context { + UINT64 stream; UINT64 length; UINT64 position; UINT64 buffer_size; diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 2cea1655719..ef718289f9d 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) +@ cdecl winedmo_demuxer_create(ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index e60995d4f6b..07192242a2a 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -26,10 +26,16 @@ #include "winbase.h" #include "winternl.h"
+struct winedmo_stream +{ + NTSTATUS (CDECL *p_seek)( struct winedmo_stream *stream, UINT64 *pos ); + NTSTATUS (CDECL *p_read)( struct winedmo_stream *stream, BYTE *buffer, ULONG *size ); +}; + struct winedmo_demuxer { UINT64 handle; };
NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ); -NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_demuxer *demuxer ); +NTSTATUS CDECL winedmo_demuxer_create( struct winedmo_stream *stream, UINT64 *stream_size, struct winedmo_demuxer *demuxer ); NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer );
#endif /* __WINE_WINEDMO_H */