From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winedmo/winedmo.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 3e9cc721f56..dd88fa74e5b 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,4 +1,4 @@ @ cdecl winedmo_demuxer_check(str) -@ cdecl winedmo_demuxer_create(wstr ptr ptr ptr ptr ptr ptr) +@ cdecl winedmo_demuxer_create(wstr ptr int64 ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) @ cdecl winedmo_demuxer_stream_type(int64 long ptr ptr)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winedmo/main.c | 19 +++++++++++++++++++ dlls/winedmo/unix_demuxer.c | 16 ++++++++++++++++ dlls/winedmo/unix_private.h | 1 + dlls/winedmo/unixlib.c | 2 ++ dlls/winedmo/unixlib.h | 8 ++++++++ dlls/winedmo/winedmo.spec | 1 + include/wine/winedmo.h | 1 + 7 files changed, 48 insertions(+)
diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 0751337659a..2f16120796d 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -180,6 +180,25 @@ NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer ) return status; }
+NTSTATUS CDECL winedmo_demuxer_stream_name( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ) +{ + struct demuxer_stream_name_params params = {.demuxer = demuxer, .stream = stream}; + NTSTATUS status; + + TRACE( "demuxer %#I64x, stream %u\n", demuxer.handle, stream ); + + if ((status = UNIX_CALL( demuxer_stream_name, ¶ms ))) + { + WARN( "Failed to get stream name, status %#lx\n", status ); + return status; + } + + len = MultiByteToWideChar( CP_UTF8, 0, params.buffer, -1, buffer, len ); + buffer[len - 1] = 0; + return STATUS_SUCCESS; +} + + static HRESULT get_media_type( UINT code, void *params, struct media_type *media_type, GUID *major, union winedmo_format **format ) { diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index 632b75480d7..d4064b0fc0f 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -159,6 +159,22 @@ NTSTATUS demuxer_destroy( void *arg ) return STATUS_SUCCESS; }
+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]; + AVDictionaryEntry *tag; + + TRACE( "context %p, stream %u\n", ctx, params->stream ); + + if (!(tag = av_dict_get( stream->metadata, "title", NULL, AV_DICT_IGNORE_SUFFIX ))) + return STATUS_NOT_FOUND; + + lstrcpynA( params->buffer, tag->value, ARRAY_SIZE( params->buffer ) ); + return STATUS_SUCCESS; +} + NTSTATUS demuxer_stream_type( void *arg ) { struct demuxer_stream_type_params *params = arg; diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index bb91e06449b..1bb73efeb99 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_stream_name( void * ); extern NTSTATUS demuxer_stream_type( void * );
/* unix_media_type.c */ diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 13178ec5260..57318e864e0 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_name ), X( demuxer_stream_type ), };
@@ -191,6 +192,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = X( demuxer_check ), X64( demuxer_create ), X64( demuxer_destroy ), + X( demuxer_stream_name ), X( demuxer_stream_type ), };
diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index 9e1bdd14ad2..2f1d1016fd2 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -98,6 +98,13 @@ struct demuxer_destroy_params struct stream_context *context; };
+struct demuxer_stream_name_params +{ + struct winedmo_demuxer demuxer; + UINT32 stream; + char buffer[256]; +}; + struct demuxer_stream_type_params { struct winedmo_demuxer demuxer; @@ -113,6 +120,7 @@ enum unix_funcs unix_demuxer_check, unix_demuxer_create, unix_demuxer_destroy, + unix_demuxer_stream_name, unix_demuxer_stream_type,
unix_funcs_count, diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index dd88fa74e5b..991efb52164 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,4 +1,5 @@ @ cdecl winedmo_demuxer_check(str) @ cdecl winedmo_demuxer_create(wstr ptr int64 ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) +@ cdecl winedmo_demuxer_stream_name(int64 long ptr long) @ cdecl winedmo_demuxer_stream_type(int64 long ptr ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index 7f9fb08bebd..c1aa2c2255c 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_stream_name( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ); NTSTATUS CDECL winedmo_demuxer_stream_type( struct winedmo_demuxer demuxer, UINT stream, GUID *major, union winedmo_format **format );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 6c367111b49..2d25367820c 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -815,6 +815,24 @@ static void media_source_init_stream_map(struct media_source *source, UINT strea } }
+static void media_source_init_descriptors(struct media_source *source) +{ + UINT i; + + TRACE("source %p\n", source); + + for (i = 0; i < source->stream_count; i++) + { + struct media_stream *stream = source->streams[i]; + WCHAR buffer[512]; + NTSTATUS status; + + if (FAILED(status = winedmo_demuxer_stream_name(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) + || FAILED(IMFStreamDescriptor_SetString(stream->descriptor, &MF_SD_STREAM_NAME, buffer))) + WARN("Failed to set stream descriptor name, status %#lx\n", status); + } +} + static HRESULT stream_descriptor_create(UINT32 id, IMFMediaType *media_type, IMFStreamDescriptor **out) { IMFStreamDescriptor *descriptor; @@ -916,6 +934,8 @@ static HRESULT media_source_async_create(struct media_source *source, IMFAsyncRe IMFMediaType_Release(media_type); }
+ media_source_init_descriptors(source); + done: IMFAsyncResult_SetStatus(result, hr); return MFInvokeCallback((IMFAsyncResult *)state);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winedmo/main.c | 18 ++++++++++++++++++ dlls/winedmo/unix_demuxer.c | 16 ++++++++++++++++ dlls/winedmo/unix_private.h | 1 + dlls/winedmo/unixlib.c | 2 ++ dlls/winedmo/unixlib.h | 8 ++++++++ dlls/winedmo/winedmo.spec | 1 + include/wine/winedmo.h | 1 + 7 files changed, 47 insertions(+)
diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 2f16120796d..381211b396f 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -180,6 +180,24 @@ NTSTATUS CDECL winedmo_demuxer_destroy( struct winedmo_demuxer *demuxer ) return status; }
+NTSTATUS CDECL winedmo_demuxer_stream_lang( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ) +{ + struct demuxer_stream_lang_params params = {.demuxer = demuxer, .stream = stream}; + NTSTATUS status; + + TRACE( "demuxer %#I64x, stream %u\n", demuxer.handle, stream ); + + if ((status = UNIX_CALL( demuxer_stream_lang, ¶ms ))) + { + WARN( "Failed to get stream lang, status %#lx\n", status ); + return status; + } + + len = MultiByteToWideChar( CP_UTF8, 0, params.buffer, -1, buffer, len ); + buffer[len - 1] = 0; + return STATUS_SUCCESS; +} + NTSTATUS CDECL winedmo_demuxer_stream_name( struct winedmo_demuxer demuxer, UINT stream, WCHAR *buffer, UINT len ) { struct demuxer_stream_name_params params = {.demuxer = demuxer, .stream = stream}; diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index d4064b0fc0f..70f9e0715f6 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -159,6 +159,22 @@ NTSTATUS demuxer_destroy( void *arg ) return STATUS_SUCCESS; }
+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]; + AVDictionaryEntry *tag; + + TRACE( "context %p, stream %u\n", ctx, params->stream ); + + if (!(tag = av_dict_get( stream->metadata, "language", NULL, AV_DICT_IGNORE_SUFFIX ))) + return STATUS_NOT_FOUND; + + lstrcpynA( params->buffer, tag->value, ARRAY_SIZE( params->buffer ) ); + return STATUS_SUCCESS; +} + NTSTATUS demuxer_stream_name( void *arg ) { struct demuxer_stream_name_params *params = arg; diff --git a/dlls/winedmo/unix_private.h b/dlls/winedmo/unix_private.h index 1bb73efeb99..8a282c23148 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_stream_lang( void * ); extern NTSTATUS demuxer_stream_name( void * ); extern NTSTATUS demuxer_stream_type( void * );
diff --git a/dlls/winedmo/unixlib.c b/dlls/winedmo/unixlib.c index 57318e864e0..8398c8f143a 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_lang ), X( demuxer_stream_name ), X( demuxer_stream_type ), }; @@ -192,6 +193,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = X( demuxer_check ), X64( demuxer_create ), X64( demuxer_destroy ), + X( demuxer_stream_lang ), X( demuxer_stream_name ), X( demuxer_stream_type ), }; diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index 2f1d1016fd2..d7dc1a2e2fd 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -98,6 +98,13 @@ struct demuxer_destroy_params struct stream_context *context; };
+struct demuxer_stream_lang_params +{ + struct winedmo_demuxer demuxer; + UINT32 stream; + char buffer[32]; +}; + struct demuxer_stream_name_params { struct winedmo_demuxer demuxer; @@ -120,6 +127,7 @@ enum unix_funcs unix_demuxer_check, unix_demuxer_create, unix_demuxer_destroy, + unix_demuxer_stream_lang, unix_demuxer_stream_name, unix_demuxer_stream_type,
diff --git a/dlls/winedmo/winedmo.spec b/dlls/winedmo/winedmo.spec index 991efb52164..0da65562406 100644 --- a/dlls/winedmo/winedmo.spec +++ b/dlls/winedmo/winedmo.spec @@ -1,5 +1,6 @@ @ cdecl winedmo_demuxer_check(str) @ cdecl winedmo_demuxer_create(wstr ptr int64 ptr ptr ptr ptr) @ cdecl winedmo_demuxer_destroy(ptr) +@ cdecl winedmo_demuxer_stream_lang(int64 long ptr long) @ cdecl winedmo_demuxer_stream_name(int64 long ptr long) @ cdecl winedmo_demuxer_stream_type(int64 long ptr ptr) diff --git a/include/wine/winedmo.h b/include/wine/winedmo.h index c1aa2c2255c..843640c8107 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_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 ); NTSTATUS CDECL winedmo_demuxer_stream_type( struct winedmo_demuxer demuxer, UINT stream, GUID *major, union winedmo_format **format );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 2d25367820c..8ac3699a01f 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -815,6 +815,47 @@ static void media_source_init_stream_map(struct media_source *source, UINT strea } }
+static HRESULT normalize_mp4_language_code(struct media_source *source, WCHAR *buffer) +{ + static const WCHAR mapping[] = L"aar:aa,abk:ab,ave:ae,afr:af,aka:ak,amh:am,arg:an," + "ara:ar,asm:as,ava:av,aym:ay,aze:az,bak:ba,bel:be," + "bul:bg,bih:bh,bis:bi,bam:bm,ben:bn,bod:bo,tib:bo," + "bre:br,bos:bs,cat:ca,che:ce,cha:ch,cos:co,cre:cr," + "ces:cs,cze:cs,chu:cu,chv:cv,cym:cy,wel:cy,dan:da," + "deu:de,ger:de,div:dv,dzo:dz,ewe:ee,ell:el,gre:el," + "eng:en,epo:eo,spa:es,est:et,eus:eu,baq:eu,fas:fa," + "per:fa,ful:ff,fin:fi,fij:fj,fao:fo,fra:fr,fre:fr," + "fry:fy,gle:ga,gla:gd,glg:gl,grn:gn,guj:gu,glv:gv," + "hau:ha,heb:he,hin:hi,hmo:ho,hrv:hr,hat:ht,hun:hu," + "hye:hy,arm:hy,her:hz,ina:ia,ind:id,ile:ie,ibo:ig," + "iii:ii,ipk:ik,ido:io,isl:is,ice:is,ita:it,iku:iu," + "jpn:ja,jav:jv,kat:ka,geo:ka,kon:kg,kik:ki,kua:kj," + "kaz:kk,kal:kl,khm:km,kan:kn,kor:ko,kau:kr,kas:ks," + "kur:ku,kom:kv,cor:kw,kir:ky,lat:la,ltz:lb,lug:lg," + "lim:li,lin:ln,lao:lo,lit:lt,lub:lu,lav:lv,mlg:mg," + "mah:mh,mri:mi,mao:mi,mkd:mk,mac:mk,mal:ml,mon:mn," + "mar:mr,msa:ms,may:ms,mlt:mt,mya:my,bur:my,nau:na," + "nob:nb,nde:nd,nep:ne,ndo:ng,nld:nl,dut:nl,nno:nn," + "nor:no,nbl:nr,nav:nv,nya:ny,oci:oc,oji:oj,orm:om," + "ori:or,oss:os,pan:pa,pli:pi,pol:pl,pus:ps,por:pt," + "que:qu,roh:rm,run:rn,ron:ro,rum:ro,rus:ru,kin:rw," + "san:sa,srd:sc,snd:sd,sme:se,sag:sg,sin:si,slk:sk," + "slo:sk,slv:sl,smo:sm,sna:sn,som:so,sqi:sq,alb:sq," + "srp:sr,ssw:ss,sot:st,sun:su,swe:sv,swa:sw,tam:ta," + "tel:te,tgk:tg,tha:th,tir:ti,tuk:tk,tgl:tl,tsn:tn," + "ton:to,tur:tr,tso:ts,tat:tt,twi:tw,tah:ty,uig:ug," + "ukr:uk,urd:ur,uzb:uz,ven:ve,vie:vi,vol:vo,wln:wa," + "wol:wo,xho:xh,yid:yi,yor:yo,zha:za,zho:zh,chi:zh," + "zul:zu"; + const WCHAR *tmp; + TRACE("source %p, buffer %s\n", source, debugstr_w(buffer)); + + if (wcslen(buffer) != 3) return S_OK; + if ((tmp = wcsstr(mapping, buffer)) && tmp[3] == ':') lstrcpynW(buffer, tmp + 4, 3); + if (!tmp) return E_UNEXPECTED; + return S_OK; +} + static void media_source_init_descriptors(struct media_source *source) { UINT i; @@ -827,6 +868,10 @@ static void media_source_init_descriptors(struct media_source *source) WCHAR buffer[512]; NTSTATUS status;
+ if (FAILED(status = winedmo_demuxer_stream_lang(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) + || (!wcscmp(source->mime_type, L"video/mp4") && FAILED(normalize_mp4_language_code(source, buffer))) + || FAILED(IMFStreamDescriptor_SetString(stream->descriptor, &MF_SD_LANGUAGE, buffer))) + WARN("Failed to set stream descriptor language, status %#lx\n", status); if (FAILED(status = winedmo_demuxer_stream_name(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) || FAILED(IMFStreamDescriptor_SetString(stream->descriptor, &MF_SD_STREAM_NAME, buffer))) WARN("Failed to set stream descriptor name, status %#lx\n", status);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 50 +++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index 8ac3699a01f..2b59ee89f3e 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -80,6 +80,8 @@ struct media_stream IMFMediaSource *source; IMFMediaEventQueue *queue; IMFStreamDescriptor *descriptor; + + BOOL active; };
struct media_source @@ -161,6 +163,7 @@ static ULONG WINAPI media_stream_Release(IMFMediaStream *iface)
if (!refcount) { + stream->active = FALSE; IMFMediaSource_Release(stream->source); IMFStreamDescriptor_Release(stream->descriptor); IMFMediaEventQueue_Release(stream->queue); @@ -636,6 +639,8 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *
for (i = 0; i < source->stream_count; ++i) { + if (!source->streams[i]->active) + continue; if (FAILED(hr = IMFPresentationDescriptor_SelectStream(*descriptor, i))) WARN("Failed to select stream %u, hr %#lx\n", i, hr); } @@ -858,15 +863,17 @@ static HRESULT normalize_mp4_language_code(struct media_source *source, WCHAR *b
static void media_source_init_descriptors(struct media_source *source) { - UINT i; + UINT i, last_audio = -1, last_video = -1, first_audio = -1, first_video = -1;
TRACE("source %p\n", source);
for (i = 0; i < source->stream_count; i++) { struct media_stream *stream = source->streams[i]; + UINT exclude = -1; WCHAR buffer[512]; NTSTATUS status; + GUID major;
if (FAILED(status = winedmo_demuxer_stream_lang(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) || (!wcscmp(source->mime_type, L"video/mp4") && FAILED(normalize_mp4_language_code(source, buffer))) @@ -875,6 +882,47 @@ static void media_source_init_descriptors(struct media_source *source) if (FAILED(status = winedmo_demuxer_stream_name(source->winedmo_demuxer, source->stream_map[i], buffer, ARRAY_SIZE(buffer))) || FAILED(IMFStreamDescriptor_SetString(stream->descriptor, &MF_SD_STREAM_NAME, buffer))) WARN("Failed to set stream descriptor name, status %#lx\n", status); + + if (FAILED(get_stream_media_type(source->winedmo_demuxer, source->stream_map[i], &major, NULL))) + continue; + + if (IsEqualGUID(&major, &MFMediaType_Audio)) + { + if (first_audio == -1) + first_audio = i; + exclude = last_audio; + last_audio = i; + } + else if (IsEqualGUID(&major, &MFMediaType_Video)) + { + if (first_video == -1) + first_video = i; + exclude = last_video; + last_video = i; + } + + if (exclude != -1) + { + if (FAILED(IMFStreamDescriptor_SetUINT32(source->streams[exclude]->descriptor, &MF_SD_MUTUALLY_EXCLUSIVE, 1))) + WARN("Failed to set stream %u MF_SD_MUTUALLY_EXCLUSIVE\n", exclude); + else if (FAILED(IMFStreamDescriptor_SetUINT32(stream->descriptor, &MF_SD_MUTUALLY_EXCLUSIVE, 1))) + WARN("Failed to set stream %u MF_SD_MUTUALLY_EXCLUSIVE\n", i); + } + } + + if (!wcscmp(source->mime_type, L"video/mp4")) + { + if (last_audio != -1) + source->streams[last_audio]->active = TRUE; + if (last_video != -1) + source->streams[last_video]->active = TRUE; + } + else + { + if (first_audio != -1) + source->streams[first_audio]->active = TRUE; + if (first_video != -1) + source->streams[first_video]->active = TRUE; } }