From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winedmo/Makefile.in | 1 + dlls/winedmo/main.c | 51 +++++++++++++++++++++++++++++++++++++ dlls/winedmo/unix_demuxer.c | 38 +++++++++++++++++++++++++++ dlls/winedmo/unix_private.h | 1 + dlls/winedmo/unixlib.c | 2 ++ dlls/winedmo/unixlib.h | 16 ++++++++++++ dlls/winedmo/winedmo.spec | 1 + include/wine/winedmo.h | 1 + 8 files changed, 111 insertions(+)
diff --git a/dlls/winedmo/Makefile.in b/dlls/winedmo/Makefile.in index 2d829deb07b..9b33d859d6a 100644 --- a/dlls/winedmo/Makefile.in +++ b/dlls/winedmo/Makefile.in @@ -1,6 +1,7 @@ MODULE = winedmo.dll UNIXLIB = winedmo.so IMPORTLIB = winedmo +IMPORTS = mfuuid UNIX_CFLAGS = $(FFMPEG_CFLAGS) UNIX_LIBS = $(FFMPEG_LIBS) $(PTHREAD_LIBS)
diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index ccb8a4eb95d..7536566fe75 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -16,8 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#define COBJMACROS #include "unixlib.h" #include "winnls.h" +#include "mfidl.h"
#include "wine/debug.h"
@@ -114,6 +116,32 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) }
+static void buffer_lock( DMO_OUTPUT_DATA_BUFFER *buffer, struct sample *sample ) +{ + BYTE *data; + HRESULT hr; + DWORD size; + + if (FAILED(hr = IMediaBuffer_GetBufferAndLength( buffer->pBuffer, &data, &size ))) + ERR( "Failed to get media buffer data %p, hr %#lx\n", buffer, hr ); + if (FAILED(hr = IMediaBuffer_GetMaxLength( buffer->pBuffer, &size ))) + ERR( "Failed to get media buffer max length %p, hr %#lx\n", buffer, hr ); + + sample->data = (UINT_PTR)data; + sample->size = size; +} + +static void buffer_unlock( DMO_OUTPUT_DATA_BUFFER *buffer, struct sample *sample ) +{ + HRESULT hr; + + if (FAILED(hr = IMediaBuffer_SetLength( buffer->pBuffer, sample->size ))) + ERR( "Failed to update buffer length, hr %#lx\n", hr ); + + buffer->dwStatus = 0; +} + + NTSTATUS CDECL winedmo_demuxer_check( const char *mime_type ) { struct demuxer_check_params params = {0}; @@ -180,6 +208,29 @@ 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 ) +{ + struct demuxer_read_params params = {.demuxer = demuxer}; + NTSTATUS status; + + TRACE( "demuxer %#I64x, stream %p, buffer %p, buffer_size %p\n", demuxer.handle, stream, buffer, buffer_size ); + + buffer_lock( buffer, ¶ms.sample ); + status = UNIX_CALL( demuxer_read, ¶ms ); + buffer_unlock( buffer, ¶ms.sample ); + *buffer_size = params.sample.size; + *stream = params.stream; + + if (status) + { + ERR( "Failed to read sample, status %#lx\n", status ); + return status; + } + + TRACE( "Got buffer %p, buffer_size %#x on stream %u\n", buffer->pBuffer, *buffer_size, *stream ); + return status; +} + NTSTATUS CDECL winedmo_demuxer_seek( struct winedmo_demuxer demuxer, INT64 timestamp ) { struct demuxer_seek_params params = {.demuxer = demuxer, .timestamp = timestamp}; diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index e14431e6d9c..d3e804aa6eb 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -159,6 +159,44 @@ NTSTATUS demuxer_destroy( void *arg ) return STATUS_SUCCESS; }
+NTSTATUS demuxer_read( void *arg ) +{ + struct demuxer_read_params *params = arg; + AVFormatContext *ctx = get_demuxer( params->demuxer ); + struct sample *sample = ¶ms->sample; + UINT capacity = params->sample.size; + AVPacket *packet; + int ret; + + TRACE( "context %p, capacity %#x\n", ctx, capacity ); + + if (!(packet = ctx->opaque)) + { + if (!(packet = av_packet_alloc())) return STATUS_NO_MEMORY; + if ((ret = av_read_frame( ctx, packet )) < 0) + { + TRACE( "Failed to read context %p, error %s.\n", ctx, debugstr_averr( ret ) ); + av_packet_free( &packet ); + if (ret == AVERROR_EOF) return STATUS_END_OF_FILE; + return STATUS_UNSUCCESSFUL; + } + } + + params->sample.size = packet->size; + if ((capacity < packet->size)) + { + ctx->opaque = packet; + return STATUS_BUFFER_TOO_SMALL; + } + + memcpy( (void *)(UINT_PTR)sample->data, packet->data, packet->size ); + params->stream = packet->stream_index; + av_packet_free( &packet ); + ctx->opaque = NULL; + + return STATUS_SUCCESS; +} + NTSTATUS demuxer_seek( void *arg ) { struct demuxer_seek_params *params = arg; diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index 77aa9058350..bc45f2c6db2 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -43,6 +43,7 @@ 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_read( void * ); extern NTSTATUS demuxer_seek( void * ); extern NTSTATUS demuxer_stream_lang( void * ); extern NTSTATUS demuxer_stream_name( void * ); diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 119853ec457..15500ee10b4 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_read ), X( demuxer_seek ), X( demuxer_stream_lang ), X( demuxer_stream_name ), @@ -194,6 +195,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = X( demuxer_check ), X64( demuxer_create ), X64( demuxer_destroy ), + X( demuxer_read ), X( demuxer_seek ), X( demuxer_stream_lang ), X( demuxer_stream_name ), diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index fd250e58209..4e3fef9fa82 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -21,6 +21,7 @@
#include <stddef.h> #include <stdarg.h> +#include <stdint.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -63,6 +64,13 @@ struct read_callback_params };
+struct sample +{ + UINT64 size; + UINT64 data; /* pointer to user memory */ +}; + + struct media_type { GUID major; @@ -98,6 +106,13 @@ struct demuxer_destroy_params struct stream_context *context; };
+struct demuxer_read_params +{ + struct winedmo_demuxer demuxer; + UINT32 stream; + struct sample sample; +}; + struct demuxer_seek_params { struct winedmo_demuxer demuxer; @@ -133,6 +148,7 @@ enum unix_funcs unix_demuxer_check, unix_demuxer_create, unix_demuxer_destroy, + unix_demuxer_read, unix_demuxer_seek, unix_demuxer_stream_lang, unix_demuxer_stream_name, diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 77772b1f472..90eff030dfd 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,6 +1,7 @@ @ 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) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index f4f9d1371d4..c068dfa1de8 100644 --- a/include/wine/winedmo.h +++ b/include/wine/winedmo.h @@ -46,6 +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_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 );