From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/gst_private.h | 3 +- dlls/winegstreamer/main.c | 7 ++-- dlls/winegstreamer/media_sink.c | 72 ++++++++++++++++++++++++++------ 3 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 0c814148447..243dab16c72 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -125,7 +125,8 @@ HRESULT wma_decoder_create(IUnknown *outer, IUnknown **out); HRESULT wmv_decoder_create(IUnknown *outer, IUnknown **out); HRESULT resampler_create(IUnknown *outer, IUnknown **out); HRESULT color_convert_create(IUnknown *outer, IUnknown **out); -HRESULT sink_class_factory_create(IUnknown *outer, IUnknown **out); +HRESULT mp3_sink_class_factory_create(IUnknown *outer, IUnknown **out); +HRESULT mpeg4_sink_class_factory_create(IUnknown *outer, IUnknown **out);
bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool wm); bool amt_to_wg_format(const AM_MEDIA_TYPE *mt, struct wg_format *format); diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index e1ddf1e52f7..e4c93076eea 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -638,7 +638,8 @@ static struct class_factory wma_decoder_cf = {{&class_factory_vtbl}, wma_decoder static struct class_factory wmv_decoder_cf = {{&class_factory_vtbl}, wmv_decoder_create}; static struct class_factory resampler_cf = {{&class_factory_vtbl}, resampler_create}; static struct class_factory color_convert_cf = {{&class_factory_vtbl}, color_convert_create}; -static struct class_factory sink_class_factory_cf = {{&class_factory_vtbl}, sink_class_factory_create}; +static struct class_factory mp3_sink_class_factory_cf = {{&class_factory_vtbl}, mp3_sink_class_factory_create}; +static struct class_factory mpeg4_sink_class_factory_cf = {{&class_factory_vtbl}, mpeg4_sink_class_factory_create};
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) { @@ -674,9 +675,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) else if (IsEqualGUID(clsid, &CLSID_CColorConvertDMO)) factory = &color_convert_cf; else if (IsEqualGUID(clsid, &CLSID_MFMP3SinkClassFactory)) - factory = &sink_class_factory_cf; + factory = &mp3_sink_class_factory_cf; else if (IsEqualGUID(clsid, &CLSID_MFMPEG4SinkClassFactory)) - factory = &sink_class_factory_cf; + factory = &mpeg4_sink_class_factory_cf; else { FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid)); diff --git a/dlls/winegstreamer/media_sink.c b/dlls/winegstreamer/media_sink.c index fcea67eb8f1..392ffb17bf9 100644 --- a/dlls/winegstreamer/media_sink.c +++ b/dlls/winegstreamer/media_sink.c @@ -72,11 +72,14 @@ struct media_sink STATE_PAUSED, STATE_SHUTDOWN, } state; + struct wg_container_format format;
IMFByteStream *bytestream; IMFMediaEventQueue *event_queue;
struct list stream_sinks; + + wg_muxer_t muxer; };
static struct stream_sink *impl_from_IMFStreamSink(IMFStreamSink *iface) @@ -567,6 +570,7 @@ static ULONG WINAPI media_sink_Release(IMFFinalizableMediaSink *iface) IMFByteStream_Release(media_sink->bytestream); media_sink->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&media_sink->cs); + wg_muxer_destroy(media_sink->muxer); free(media_sink); }
@@ -1022,7 +1026,7 @@ static const IMFAsyncCallbackVtbl media_sink_callback_vtbl = media_sink_callback_Invoke, };
-static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink **out) +static HRESULT media_sink_create(IMFByteStream *bytestream, struct wg_container_format *format, struct media_sink **out) { struct media_sink *media_sink; HRESULT hr; @@ -1035,11 +1039,10 @@ static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink ** if (!(media_sink = calloc(1, sizeof(*media_sink)))) return E_OUTOFMEMORY;
+ if (FAILED(hr = wg_muxer_create(format, &media_sink->muxer))) + goto fail; if (FAILED(hr = MFCreateEventQueue(&media_sink->event_queue))) - { - free(media_sink); - return hr; - } + goto fail;
media_sink->IMFFinalizableMediaSink_iface.lpVtbl = &media_sink_vtbl; media_sink->IMFMediaEventGenerator_iface.lpVtbl = &media_sink_event_vtbl; @@ -1047,6 +1050,7 @@ static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink ** media_sink->async_callback.lpVtbl = &media_sink_callback_vtbl; media_sink->refcount = 1; media_sink->state = STATE_OPENED; + media_sink->format = *format; InitializeCriticalSection(&media_sink->cs); media_sink->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs"); IMFByteStream_AddRef((media_sink->bytestream = bytestream)); @@ -1056,6 +1060,14 @@ static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink ** TRACE("Created media sink %p.\n", media_sink);
return S_OK; + +fail: + if (media_sink->event_queue) + IMFMediaEventQueue_Release(media_sink->event_queue); + if (media_sink->muxer) + wg_muxer_destroy(media_sink->muxer); + free(media_sink); + return hr; }
static HRESULT WINAPI sink_class_factory_QueryInterface(IMFSinkClassFactory *iface, REFIID riid, void **out) @@ -1082,8 +1094,8 @@ static ULONG WINAPI sink_class_factory_Release(IMFSinkClassFactory *iface) return 1; }
-static HRESULT WINAPI sink_class_factory_CreateMediaSink(IMFSinkClassFactory *iface, IMFByteStream *bytestream, - IMFMediaType *video_type, IMFMediaType *audio_type, IMFMediaSink **out) +static HRESULT WINAPI sink_class_factory_create_media_sink(IMFSinkClassFactory *iface, IMFByteStream *bytestream, + struct wg_container_format *format, IMFMediaType *video_type, IMFMediaType *audio_type, IMFMediaSink **out) { IMFFinalizableMediaSink *media_sink_iface; struct media_sink *media_sink; @@ -1092,7 +1104,7 @@ static HRESULT WINAPI sink_class_factory_CreateMediaSink(IMFSinkClassFactory *if TRACE("iface %p, bytestream %p, video_type %p, audio_type %p, out %p.\n", iface, bytestream, video_type, audio_type, out);
- if (FAILED(hr = media_sink_create(bytestream, &media_sink))) + if (FAILED(hr = media_sink_create(bytestream, format, &media_sink))) return hr; media_sink_iface = &media_sink->IMFFinalizableMediaSink_iface;
@@ -1119,18 +1131,52 @@ static HRESULT WINAPI sink_class_factory_CreateMediaSink(IMFSinkClassFactory *if return S_OK; }
-static const IMFSinkClassFactoryVtbl sink_class_factory_vtbl = +static HRESULT WINAPI mp3_sink_class_factory_CreateMediaSink(IMFSinkClassFactory *iface, IMFByteStream *bytestream, + IMFMediaType *video_type, IMFMediaType *audio_type, IMFMediaSink **out) +{ + struct wg_container_format format; + + format.type = WG_CONTAINER_TYPE_ID3; + return sink_class_factory_create_media_sink(iface, bytestream, &format, video_type, audio_type, out); +} + +static HRESULT WINAPI mpeg4_sink_class_factory_CreateMediaSink(IMFSinkClassFactory *iface, IMFByteStream *bytestream, + IMFMediaType *video_type, IMFMediaType *audio_type, IMFMediaSink **out) +{ + struct wg_container_format format; + + format.type = WG_CONTAINER_TYPE_QUICKTIME; + format.quicktime_variant = WG_QUICKTIME_VARIANT_ISO; + return sink_class_factory_create_media_sink(iface, bytestream, &format, video_type, audio_type, out); +} + +static const IMFSinkClassFactoryVtbl mp3_sink_class_factory_vtbl = +{ + sink_class_factory_QueryInterface, + sink_class_factory_AddRef, + sink_class_factory_Release, + mp3_sink_class_factory_CreateMediaSink, +}; + +static const IMFSinkClassFactoryVtbl mpeg4_sink_class_factory_vtbl = { sink_class_factory_QueryInterface, sink_class_factory_AddRef, sink_class_factory_Release, - sink_class_factory_CreateMediaSink, + mpeg4_sink_class_factory_CreateMediaSink, };
-static IMFSinkClassFactory sink_class_factory = { &sink_class_factory_vtbl }; +static IMFSinkClassFactory mp3_sink_class_factory = { &mp3_sink_class_factory_vtbl }; +static IMFSinkClassFactory mpeg4_sink_class_factory = { &mpeg4_sink_class_factory_vtbl }; + +HRESULT mp3_sink_class_factory_create(IUnknown *outer, IUnknown **out) +{ + *out = (IUnknown *)&mp3_sink_class_factory; + return S_OK; +}
-HRESULT sink_class_factory_create(IUnknown *outer, IUnknown **out) +HRESULT mpeg4_sink_class_factory_create(IUnknown *outer, IUnknown **out) { - *out = (IUnknown *)&sink_class_factory; + *out = (IUnknown *)&mpeg4_sink_class_factory; return S_OK; }