From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winedmo/unix_demuxer.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 50be8688397..12fd998e7e4 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -91,6 +91,7 @@ NTSTATUS demuxer_create( void *arg ) { struct demuxer_create_params *params = arg; const char *ext = params->url ? strrchr( params->url, '.' ) : ""; + const AVInputFormat *format; AVFormatContext *ctx; int ret;
@@ -110,6 +111,7 @@ NTSTATUS demuxer_create( void *arg ) avformat_free_context( ctx ); return STATUS_UNSUCCESSFUL; } + format = ctx->iformat;
if ((params->duration = get_context_duration( ctx )) == AV_NOPTS_VALUE) { @@ -125,12 +127,12 @@ NTSTATUS demuxer_create( void *arg )
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" ); - 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" )) + if (strstr( format->name, "mp4" )) strcpy( params->mime_type, "video/mp4" ); + else if (strstr( format->name, "avi" )) strcpy( params->mime_type, "video/avi" ); + else if (strstr( format->name, "mpeg" )) strcpy( params->mime_type, "video/mpeg" ); + else if (strstr( format->name, "mp3" )) strcpy( params->mime_type, "audio/mp3" ); + else if (strstr( format->name, "wav" )) strcpy( params->mime_type, "audio/wav" ); + else if (strstr( format->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" ); @@ -138,7 +140,7 @@ NTSTATUS demuxer_create( void *arg ) } else { - FIXME( "Unknown MIME type for format %s, url %s\n", debugstr_a(ctx->iformat->name), debugstr_a(params->url) ); + FIXME( "Unknown MIME type for format %s, url %s\n", debugstr_a(format->name), debugstr_a(params->url) ); strcpy( params->mime_type, "video/x-application" ); }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winedmo/unix_demuxer.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 12fd998e7e4..6f3264f05bd 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -98,18 +98,12 @@ NTSTATUS demuxer_create( void *arg ) 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 ))) - { - avformat_free_context( ctx ); - return STATUS_NO_MEMORY; - } + if (!(ctx->pb = avio_alloc_context( NULL, 0, 0, params->context, unix_read_callback, NULL, unix_seek_callback ))) goto failed;
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; + goto failed; } format = ctx->iformat;
@@ -117,10 +111,8 @@ NTSTATUS demuxer_create( void *arg ) { 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; + ERR( "Failed to find stream info, error %s.\n", debugstr_averr(ret) ); + goto failed; } params->duration = get_context_duration( ctx ); } @@ -145,6 +137,14 @@ NTSTATUS demuxer_create( void *arg ) }
return STATUS_SUCCESS; + +failed: + if (ctx) + { + avio_context_free( &ctx->pb ); + avformat_free_context( ctx ); + } + return STATUS_UNSUCCESSFUL; }
NTSTATUS demuxer_destroy( void *arg )
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winedmo/unix_demuxer.c | 90 ++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 41 deletions(-)
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 6f3264f05bd..d40b80da326 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -34,9 +34,14 @@ 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 ) +struct demuxer { - return (AVFormatContext *)(UINT_PTR)demuxer.handle; + AVFormatContext *ctx; +}; + +static struct demuxer *get_demuxer( struct winedmo_demuxer demuxer ) +{ + return (struct demuxer *)(UINT_PTR)demuxer.handle; }
static INT64 get_user_time( INT64 time, AVRational time_base ) @@ -92,33 +97,34 @@ NTSTATUS demuxer_create( void *arg ) struct demuxer_create_params *params = arg; const char *ext = params->url ? strrchr( params->url, '.' ) : ""; const AVInputFormat *format; - AVFormatContext *ctx; + struct demuxer *demuxer; int ret;
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 ))) goto failed; + if (!(demuxer = calloc( 1, sizeof(*demuxer) ))) return STATUS_NO_MEMORY; + if (!(demuxer->ctx = avformat_alloc_context())) goto failed; + if (!(demuxer->ctx->pb = avio_alloc_context( NULL, 0, 0, params->context, unix_read_callback, NULL, unix_seek_callback ))) goto failed;
- if ((ret = avformat_open_input( &ctx, NULL, NULL, NULL )) < 0) + if ((ret = avformat_open_input( &demuxer->ctx, NULL, NULL, NULL )) < 0) { ERR( "Failed to open input, error %s.\n", debugstr_averr(ret) ); goto failed; } - format = ctx->iformat; + format = demuxer->ctx->iformat;
- if ((params->duration = get_context_duration( ctx )) == AV_NOPTS_VALUE) + if ((params->duration = get_context_duration( demuxer->ctx )) == AV_NOPTS_VALUE) { - if ((ret = avformat_find_stream_info( ctx, NULL )) < 0) + if ((ret = avformat_find_stream_info( demuxer->ctx, NULL )) < 0) { ERR( "Failed to find stream info, error %s.\n", debugstr_averr(ret) ); goto failed; } - params->duration = get_context_duration( ctx ); + params->duration = get_context_duration( demuxer->ctx ); }
- params->demuxer.handle = (UINT_PTR)ctx; - params->stream_count = ctx->nb_streams; + params->demuxer.handle = (UINT_PTR)demuxer; + params->stream_count = demuxer->ctx->nb_streams; if (strstr( format->name, "mp4" )) strcpy( params->mime_type, "video/mp4" ); else if (strstr( format->name, "avi" )) strcpy( params->mime_type, "video/avi" ); else if (strstr( format->name, "mpeg" )) strcpy( params->mime_type, "video/mpeg" ); @@ -139,24 +145,26 @@ NTSTATUS demuxer_create( void *arg ) return STATUS_SUCCESS;
failed: - if (ctx) + if (demuxer->ctx) { - avio_context_free( &ctx->pb ); - avformat_free_context( ctx ); + avio_context_free( &demuxer->ctx->pb ); + avformat_free_context( demuxer->ctx ); } + free( demuxer ); return STATUS_UNSUCCESSFUL; }
NTSTATUS demuxer_destroy( void *arg ) { struct demuxer_destroy_params *params = arg; - AVFormatContext *ctx = get_demuxer( params->demuxer ); + struct demuxer *demuxer = get_demuxer( params->demuxer );
- TRACE( "context %p\n", ctx ); + TRACE( "demuxer %p\n", demuxer );
- params->context = ctx->pb->opaque; - avio_context_free( &ctx->pb ); - avformat_free_context( ctx ); + params->context = demuxer->ctx->pb->opaque; + avio_context_free( &demuxer->ctx->pb ); + avformat_free_context( demuxer->ctx ); + free( demuxer );
return STATUS_SUCCESS; } @@ -164,21 +172,21 @@ NTSTATUS demuxer_destroy( void *arg ) NTSTATUS demuxer_read( void *arg ) { struct demuxer_read_params *params = arg; - AVFormatContext *ctx = get_demuxer( params->demuxer ); + struct demuxer *demuxer = get_demuxer( params->demuxer ); struct sample *sample = ¶ms->sample; UINT capacity = params->sample.size; AVStream *stream; AVPacket *packet; int ret;
- TRACE( "context %p, capacity %#x\n", ctx, capacity ); + TRACE( "demuxer %p, capacity %#x\n", demuxer, capacity );
- if (!(packet = ctx->opaque)) + if (!(packet = demuxer->ctx->opaque)) { if (!(packet = av_packet_alloc())) return STATUS_NO_MEMORY; - if ((ret = av_read_frame( ctx, packet )) < 0) + if ((ret = av_read_frame( demuxer->ctx, packet )) < 0) { - TRACE( "Failed to read context %p, error %s.\n", ctx, debugstr_averr( ret ) ); + TRACE( "Failed to read demuxer %p, error %s.\n", demuxer, debugstr_averr( ret ) ); av_packet_free( &packet ); if (ret == AVERROR_EOF) return STATUS_END_OF_FILE; return STATUS_UNSUCCESSFUL; @@ -188,11 +196,11 @@ NTSTATUS demuxer_read( void *arg ) params->sample.size = packet->size; if ((capacity < packet->size)) { - ctx->opaque = packet; + demuxer->ctx->opaque = packet; return STATUS_BUFFER_TOO_SMALL; }
- stream = ctx->streams[packet->stream_index]; + stream = demuxer->ctx->streams[packet->stream_index]; sample->pts = get_stream_time( stream, packet->pts ); sample->dts = get_stream_time( stream, packet->dts ); sample->duration = get_stream_time( stream, packet->duration ); @@ -200,7 +208,7 @@ NTSTATUS demuxer_read( void *arg ) memcpy( (void *)(UINT_PTR)sample->data, packet->data, packet->size ); params->stream = packet->stream_index; av_packet_free( &packet ); - ctx->opaque = NULL; + demuxer->ctx->opaque = NULL;
return STATUS_SUCCESS; } @@ -208,15 +216,15 @@ NTSTATUS demuxer_read( void *arg ) NTSTATUS demuxer_seek( void *arg ) { struct demuxer_seek_params *params = arg; - AVFormatContext *ctx = get_demuxer( params->demuxer ); + struct demuxer *demuxer = get_demuxer( params->demuxer ); int64_t timestamp = params->timestamp * AV_TIME_BASE / 10000000; int ret;
- TRACE( "context %p, timestamp 0x%s\n", ctx, wine_dbgstr_longlong( params->timestamp ) ); + TRACE( "demuxer %p, timestamp 0x%s\n", demuxer, wine_dbgstr_longlong( params->timestamp ) );
- if ((ret = av_seek_frame( ctx, -1, timestamp, AVSEEK_FLAG_ANY )) < 0) + if ((ret = av_seek_frame( demuxer->ctx, -1, timestamp, AVSEEK_FLAG_ANY )) < 0) { - ERR( "Failed to seek context %p, error %s.\n", ctx, debugstr_averr(ret) ); + ERR( "Failed to seek demuxer %p, error %s.\n", demuxer, debugstr_averr(ret) ); return STATUS_UNSUCCESSFUL; }
@@ -226,11 +234,11 @@ NTSTATUS demuxer_seek( void *arg ) NTSTATUS demuxer_stream_lang( void *arg ) { struct demuxer_stream_lang_params *params = arg; - AVFormatContext *ctx = get_demuxer( params->demuxer ); - AVStream *stream = ctx->streams[params->stream]; + struct demuxer *demuxer = get_demuxer( params->demuxer ); + AVStream *stream = demuxer->ctx->streams[params->stream]; AVDictionaryEntry *tag;
- TRACE( "context %p, stream %u\n", ctx, params->stream ); + TRACE( "demuxer %p, stream %u\n", demuxer, params->stream );
if (!(tag = av_dict_get( stream->metadata, "language", NULL, AV_DICT_IGNORE_SUFFIX ))) return STATUS_NOT_FOUND; @@ -242,11 +250,11 @@ NTSTATUS demuxer_stream_lang( void *arg ) NTSTATUS demuxer_stream_name( void *arg ) { struct demuxer_stream_name_params *params = arg; - AVFormatContext *ctx = get_demuxer( params->demuxer ); - AVStream *stream = ctx->streams[params->stream]; + struct demuxer *demuxer = get_demuxer( params->demuxer ); + AVStream *stream = demuxer->ctx->streams[params->stream]; AVDictionaryEntry *tag;
- TRACE( "context %p, stream %u\n", ctx, params->stream ); + TRACE( "demuxer %p, stream %u\n", demuxer, params->stream );
if (!(tag = av_dict_get( stream->metadata, "title", NULL, AV_DICT_IGNORE_SUFFIX ))) return STATUS_NOT_FOUND; @@ -258,10 +266,10 @@ NTSTATUS demuxer_stream_name( void *arg ) 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]; + struct demuxer *demuxer = get_demuxer( params->demuxer ); + AVStream *stream = demuxer->ctx->streams[params->stream];
- TRACE( "context %p, stream %u, stream %p, index %u\n", ctx, params->stream, stream, stream->index ); + TRACE( "demuxer %p, stream %u, stream %p, index %u\n", demuxer, 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 );
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winedmo/unix_demuxer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index d40b80da326..23fc9f7993b 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -37,6 +37,8 @@ static inline const char *debugstr_averr( int err ) struct demuxer { AVFormatContext *ctx; + + AVPacket *last_packet; /* last read packet */ };
static struct demuxer *get_demuxer( struct winedmo_demuxer demuxer ) @@ -181,7 +183,7 @@ NTSTATUS demuxer_read( void *arg )
TRACE( "demuxer %p, capacity %#x\n", demuxer, capacity );
- if (!(packet = demuxer->ctx->opaque)) + if (!(packet = demuxer->last_packet)) { if (!(packet = av_packet_alloc())) return STATUS_NO_MEMORY; if ((ret = av_read_frame( demuxer->ctx, packet )) < 0) @@ -196,7 +198,7 @@ NTSTATUS demuxer_read( void *arg ) params->sample.size = packet->size; if ((capacity < packet->size)) { - demuxer->ctx->opaque = packet; + demuxer->last_packet = packet; return STATUS_BUFFER_TOO_SMALL; }
@@ -208,7 +210,7 @@ NTSTATUS demuxer_read( void *arg ) memcpy( (void *)(UINT_PTR)sample->data, packet->data, packet->size ); params->stream = packet->stream_index; av_packet_free( &packet ); - demuxer->ctx->opaque = NULL; + demuxer->last_packet = NULL;
return STATUS_SUCCESS; }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winedmo/unix_demuxer.c | 36 ++++++++++++++++++++++++++++++++++-- dlls/winedmo/unix_private.h | 1 + 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 23fc9f7993b..3da4a495c95 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -34,9 +34,15 @@ static inline const char *debugstr_averr( int err ) return wine_dbg_sprintf( "%d (%s)", err, av_err2str(err) ); }
+struct stream +{ + AVBSFContext *filter; +}; + struct demuxer { AVFormatContext *ctx; + struct stream *streams;
AVPacket *last_packet; /* last read packet */ }; @@ -94,13 +100,29 @@ NTSTATUS demuxer_check( void *arg ) return format ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED; }
+static NTSTATUS demuxer_create_streams( struct demuxer *demuxer ) +{ + UINT i; + + for (i = 0; i < demuxer->ctx->nb_streams; i++) + { + struct stream *stream = demuxer->streams + i; + + av_bsf_get_null_filter( &stream->filter ); + avcodec_parameters_copy( stream->filter->par_in, demuxer->ctx->streams[i]->codecpar ); + avcodec_parameters_copy( stream->filter->par_out, demuxer->ctx->streams[i]->codecpar ); + } + + return STATUS_SUCCESS; +} + NTSTATUS demuxer_create( void *arg ) { struct demuxer_create_params *params = arg; const char *ext = params->url ? strrchr( params->url, '.' ) : ""; const AVInputFormat *format; struct demuxer *demuxer; - int ret; + int i, ret;
TRACE( "context %p, url %s, mime %s\n", params->context, debugstr_a(params->url), debugstr_a(params->mime_type) );
@@ -124,6 +146,8 @@ NTSTATUS demuxer_create( void *arg ) } params->duration = get_context_duration( demuxer->ctx ); } + if (!(demuxer->streams = calloc( demuxer->ctx->nb_streams, sizeof(*demuxer->streams) ))) goto failed; + if (demuxer_create_streams( demuxer )) goto failed;
params->demuxer.handle = (UINT_PTR)demuxer; params->stream_count = demuxer->ctx->nb_streams; @@ -152,6 +176,9 @@ failed: avio_context_free( &demuxer->ctx->pb ); avformat_free_context( demuxer->ctx ); } + for (i = 0; demuxer->streams && i < demuxer->ctx->nb_streams; i++) + av_bsf_free( &demuxer->streams[i].filter ); + free( demuxer->streams ); free( demuxer ); return STATUS_UNSUCCESSFUL; } @@ -160,12 +187,16 @@ NTSTATUS demuxer_destroy( void *arg ) { struct demuxer_destroy_params *params = arg; struct demuxer *demuxer = get_demuxer( params->demuxer ); + int i;
TRACE( "demuxer %p\n", demuxer );
params->context = demuxer->ctx->pb->opaque; avio_context_free( &demuxer->ctx->pb ); avformat_free_context( demuxer->ctx ); + for (i = 0; i < demuxer->ctx->nb_streams; i++) + av_bsf_free( &demuxer->streams[i].filter ); + free( demuxer->streams ); free( demuxer );
return STATUS_SUCCESS; @@ -270,10 +301,11 @@ NTSTATUS demuxer_stream_type( void *arg ) struct demuxer_stream_type_params *params = arg; struct demuxer *demuxer = get_demuxer( params->demuxer ); AVStream *stream = demuxer->ctx->streams[params->stream]; + AVCodecParameters *par = demuxer->streams[params->stream].filter->par_out;
TRACE( "demuxer %p, stream %u, stream %p, index %u\n", demuxer, params->stream, stream, stream->index );
- return media_type_from_codec_params( stream->codecpar, &stream->sample_aspect_ratio, + return media_type_from_codec_params( par, &stream->sample_aspect_ratio, &stream->avg_frame_rate, 0, ¶ms->media_type ); }
diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index bc45f2c6db2..9950077cb33 100644 --- a/dlls/winedmo/unix_private.h +++ b/dlls/winedmo/unix_private.h @@ -27,6 +27,7 @@ #include <libavutil/imgutils.h> #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> +#include <libavcodec/bsf.h> #else typedef struct AVCodecParameters AVCodecParameters; typedef struct AVRational AVRational;
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winedmo/unix_demuxer.c | 68 ++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 13 deletions(-)
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 3da4a495c95..f983b370a39 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -37,6 +37,7 @@ static inline const char *debugstr_averr( int err ) struct stream { AVBSFContext *filter; + BOOL eos; };
struct demuxer @@ -45,6 +46,7 @@ struct demuxer struct stream *streams;
AVPacket *last_packet; /* last read packet */ + struct stream *last_stream; /* last read packet stream */ };
static struct demuxer *get_demuxer( struct winedmo_demuxer demuxer ) @@ -202,6 +204,50 @@ NTSTATUS demuxer_destroy( void *arg ) return STATUS_SUCCESS; }
+static NTSTATUS demuxer_filter_packet( struct demuxer *demuxer, AVPacket **packet ) +{ + int i, ret; + + do + { + if ((*packet = demuxer->last_packet)) return STATUS_SUCCESS; + if (!(*packet = av_packet_alloc())) return STATUS_NO_MEMORY; + + if (demuxer->last_stream) + { + if (!(ret = av_bsf_receive_packet( demuxer->last_stream->filter, *packet ))) return STATUS_SUCCESS; + if (ret == AVERROR_EOF) demuxer->last_stream->eos = TRUE; + if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ret = 0; + if (ret < 0) WARN( "Failed to read packet from filter, error %s.\n", debugstr_averr( ret ) ); + demuxer->last_stream = NULL; + } + + if (!ret && !(ret = av_read_frame( demuxer->ctx, *packet ))) + { + demuxer->last_stream = demuxer->streams + (*packet)->stream_index; + ret = av_bsf_send_packet( demuxer->last_stream->filter, *packet ); + if (ret < 0) WARN( "Failed to send packet to filter, error %s.\n", debugstr_averr( ret ) ); + } + else if (ret == AVERROR_EOF) + { + for (i = 0, ret = 0; !ret && i < demuxer->ctx->nb_streams; i++) + { + if (demuxer->streams[i].eos) continue; + demuxer->last_stream = demuxer->streams + i; + ret = av_bsf_send_packet( demuxer->streams[i].filter, NULL ); + } + + if (!demuxer->last_stream) return STATUS_END_OF_FILE; + } + if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ret = 0; + + av_packet_free( packet ); + } while (!ret); + + ERR( "Failed to read packet from demuxer %p, error %s.\n", demuxer, debugstr_averr( ret ) ); + return STATUS_UNSUCCESSFUL; +} + NTSTATUS demuxer_read( void *arg ) { struct demuxer_read_params *params = arg; @@ -210,21 +256,11 @@ NTSTATUS demuxer_read( void *arg ) UINT capacity = params->sample.size; AVStream *stream; AVPacket *packet; - int ret; + NTSTATUS status;
TRACE( "demuxer %p, capacity %#x\n", demuxer, capacity );
- if (!(packet = demuxer->last_packet)) - { - if (!(packet = av_packet_alloc())) return STATUS_NO_MEMORY; - if ((ret = av_read_frame( demuxer->ctx, packet )) < 0) - { - TRACE( "Failed to read demuxer %p, error %s.\n", demuxer, debugstr_averr( ret ) ); - av_packet_free( &packet ); - if (ret == AVERROR_EOF) return STATUS_END_OF_FILE; - return STATUS_UNSUCCESSFUL; - } - } + if ((status = demuxer_filter_packet( demuxer, &packet ))) return status;
params->sample.size = packet->size; if ((capacity < packet->size)) @@ -251,7 +287,7 @@ NTSTATUS demuxer_seek( void *arg ) struct demuxer_seek_params *params = arg; struct demuxer *demuxer = get_demuxer( params->demuxer ); int64_t timestamp = params->timestamp * AV_TIME_BASE / 10000000; - int ret; + int i, ret;
TRACE( "demuxer %p, timestamp 0x%s\n", demuxer, wine_dbgstr_longlong( params->timestamp ) );
@@ -261,6 +297,12 @@ NTSTATUS demuxer_seek( void *arg ) return STATUS_UNSUCCESSFUL; }
+ for (i = 0; i < demuxer->ctx->nb_streams; i++) + { + av_bsf_flush( demuxer->streams[i].filter ); + demuxer->streams[i].eos = FALSE; + } + return STATUS_SUCCESS; }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winedmo/unix_demuxer.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index f983b370a39..f540d10a744 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -108,7 +108,22 @@ static NTSTATUS demuxer_create_streams( struct demuxer *demuxer )
for (i = 0; i < demuxer->ctx->nb_streams; i++) { + AVCodecParameters *par = demuxer->ctx->streams[i]->codecpar; struct stream *stream = demuxer->streams + i; + const AVBitStreamFilter *filter; + + if (par->codec_id == AV_CODEC_ID_H264) + { + if (!(filter = av_bsf_get_by_name( "h264_mp4toannexb" ))) + ERR( "Failed to find H264 bitstream filter\n" ); + else + { + if (av_bsf_alloc( filter, &stream->filter ) < 0) return STATUS_UNSUCCESSFUL; + avcodec_parameters_copy( stream->filter->par_in, par ); + av_bsf_init( stream->filter ); + continue; + } + }
av_bsf_get_null_filter( &stream->filter ); avcodec_parameters_copy( stream->filter->par_in, demuxer->ctx->streams[i]->codecpar );