From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/mfplat.c | 138 +++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 38c719bd062..a083915cdbd 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -40,6 +40,8 @@ DEFINE_GUID(DMOVideoFormat_RGB8,D3DFMT_P8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf DEFINE_MEDIATYPE_GUID(MFAudioFormat_RAW_AAC,WAVE_FORMAT_RAW_AAC1); DEFINE_MEDIATYPE_GUID(MFVideoFormat_VC1S,MAKEFOURCC('V','C','1','S')); DEFINE_MEDIATYPE_GUID(MFVideoFormat_IV50,MAKEFOURCC('I','V','5','0')); +DEFINE_MEDIATYPE_GUID(MFAudioFormat_GStreamer,MAKEFOURCC('G','S','T','a')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_GStreamer,MAKEFOURCC('G','S','T','v'));
struct class_factory { @@ -555,6 +557,74 @@ static IMFMediaType *mf_media_type_from_wg_format_video(const struct wg_format * return NULL; }
+static IMFMediaType *mf_media_type_from_wg_format_unknown_audio(const struct wg_format *format) +{ + IMFMediaType *type; + UINT32 value; + HRESULT hr; + + if (FAILED(MFCreateMediaType(&type))) + return NULL; + if (FAILED(hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio))) + goto done; + if (FAILED(hr = IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, &MFAudioFormat_GStreamer))) + goto done; + + value = format->u.unknown_audio.rate; + if (value && FAILED(hr = IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, value))) + goto done; + value = format->u.unknown_audio.channels; + if (value && FAILED(hr = IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, value))) + goto done; + if (FAILED(hr = IMFMediaType_SetBlob(type, &MF_MT_USER_DATA, (BYTE *)format->u.unknown_audio.caps, + strlen(format->u.unknown_audio.caps) + 1))) + goto done; + +done: + if (FAILED(hr)) + { + IMFMediaType_Release(type); + return NULL; + } + return type; +} + +static IMFMediaType *mf_media_type_from_wg_format_unknown_video(const struct wg_format *format) +{ + UINT64 frame_rate, frame_size; + IMFMediaType *type; + HRESULT hr; + + if (FAILED(MFCreateMediaType(&type))) + return NULL; + if (FAILED(hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video))) + goto done; + if (FAILED(hr = IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, &MFVideoFormat_GStreamer))) + goto done; + if (FAILED(hr = IMFMediaType_SetUINT32(type, &MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0))) + goto done; + if (FAILED(hr = IMFMediaType_SetUINT32(type, &MF_MT_COMPRESSED, TRUE))) + goto done; + + frame_size = (UINT64)format->u.unknown_video.width << 32 | format->u.unknown_video.height; + if (FAILED(hr = IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE, frame_size))) + goto done; + frame_rate = (UINT64)format->u.unknown_video.fps_n << 32 | format->u.unknown_video.fps_d; + if (FAILED(hr = IMFMediaType_SetUINT64(type, &MF_MT_FRAME_RATE, frame_rate))) + goto done; + if (FAILED(hr = IMFMediaType_SetBlob(type, &MF_MT_USER_DATA, (BYTE *)format->u.unknown_video.caps, + strlen(format->u.unknown_video.caps) + 1))) + goto done; + +done: + if (FAILED(hr)) + { + IMFMediaType_Release(type); + return NULL; + } + return type; +} + IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) { switch (format->major_type) @@ -570,15 +640,17 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) FIXME("Format %u not implemented!\n", format->major_type); /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: - case WG_MAJOR_TYPE_UNKNOWN_AUDIO: - case WG_MAJOR_TYPE_UNKNOWN_VIDEO: return NULL;
case WG_MAJOR_TYPE_AUDIO: return mf_media_type_from_wg_format_audio(format); + case WG_MAJOR_TYPE_UNKNOWN_AUDIO: + return mf_media_type_from_wg_format_unknown_audio(format);
case WG_MAJOR_TYPE_VIDEO: return mf_media_type_from_wg_format_video(format); + case WG_MAJOR_TYPE_UNKNOWN_VIDEO: + return mf_media_type_from_wg_format_unknown_video(format); }
assert(0); @@ -670,6 +742,29 @@ static void mf_media_type_to_wg_format_audio_mpeg4(IMFMediaType *type, const GUI format->u.audio_mpeg4.codec_data_len = codec_data_size; }
+static void mf_media_type_to_wg_format_unknown_audio(IMFMediaType *type, struct wg_format *format) +{ + UINT32 caps_len; + BYTE *caps; + HRESULT hr; + + memset(format, 0, sizeof(*format)); + format->major_type = WG_MAJOR_TYPE_UNKNOWN_AUDIO; + + if (FAILED(hr = IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &format->u.unknown_audio.rate))) + WARN("Failed to get MF_MT_AUDIO_SAMPLES_PER_SECOND for type %p, hr %#lx.\n", type, hr); + if (FAILED(hr = IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &format->u.unknown_audio.channels))) + WARN("Failed to get MF_MT_AUDIO_NUM_CHANNELS for type %p, hr %#lx.\n", type, hr); + + if (FAILED(hr = IMFMediaType_GetAllocatedBlob(type, &MF_MT_USER_DATA, &caps, &caps_len))) + WARN("Failed to get MF_MT_USER_DATA for type %p, hr %#lx.\n", type, hr); + else + { + strcpy(format->u.unknown_audio.caps, (char *)caps); + CoTaskMemFree(caps); + } +} + static enum wg_video_format mf_video_format_to_wg(const GUID *subtype) { unsigned int i; @@ -865,6 +960,41 @@ static void mf_media_type_to_wg_format_video_indeo(IMFMediaType *type, uint32_t format->u.video_indeo.version = version; }
+static void mf_media_type_to_wg_format_unknown_video(IMFMediaType *type, struct wg_format *format) +{ + UINT64 frame_rate, frame_size; + UINT32 caps_len; + HRESULT hr; + BYTE *caps; + + memset(format, 0, sizeof(*format)); + format->major_type = WG_MAJOR_TYPE_UNKNOWN_VIDEO; + + if (FAILED(hr = IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) + WARN("Failed to get MF_MT_FRAME_SIZE for type %p, hr %#lx.\n", type, hr); + else + { + format->u.unknown_video.width = frame_size >> 32; + format->u.unknown_video.height = (UINT32)frame_size; + } + + if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate) + WARN("Failed to get MF_MT_FRAME_RATE for type %p, hr %#lx.\n", type, hr); + else + { + format->u.unknown_video.fps_n = frame_rate >> 32; + format->u.unknown_video.fps_d = (UINT32)frame_rate; + } + + if (FAILED(hr = IMFMediaType_GetAllocatedBlob(type, &MF_MT_USER_DATA, &caps, &caps_len))) + WARN("Failed to get MF_MT_USER_DATA for type %p, hr %#lx.\n", type, hr); + else + { + strcpy(format->u.unknown_video.caps, (char *)caps); + CoTaskMemFree(caps); + } +} + void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) { GUID major_type, subtype; @@ -891,6 +1021,8 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) mf_media_type_to_wg_format_audio_wma(type, &subtype, format); else if (IsEqualGUID(&subtype, &MFAudioFormat_AAC) || IsEqualGUID(&subtype, &MFAudioFormat_RAW_AAC)) mf_media_type_to_wg_format_audio_mpeg4(type, &subtype, format); + else if (IsEqualGUID(&subtype, &MFAudioFormat_GStreamer)) + mf_media_type_to_wg_format_unknown_audio(type, format); else mf_media_type_to_wg_format_audio(type, &subtype, format); } @@ -900,6 +1032,8 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) mf_media_type_to_wg_format_video_h264(type, format); else if (IsEqualGUID(&subtype, &MFVideoFormat_IV50)) mf_media_type_to_wg_format_video_indeo(type, 5, format); + else if (IsEqualGUID(&subtype, &MFVideoFormat_GStreamer)) + mf_media_type_to_wg_format_unknown_video(type, format); else mf_media_type_to_wg_format_video(type, &subtype, format); }