From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/quartz_parser.c | 52 +++++++++++++++++++++++++++++- dlls/winegstreamer/wg_format.c | 44 ++++++++++++++++++++++++- dlls/winegstreamer/wm_reader.c | 10 +++++- 3 files changed, 103 insertions(+), 3 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 5561b106327..448868b0b2c 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -538,6 +538,54 @@ static bool amt_from_wg_format_video_cinepak(AM_MEDIA_TYPE *mt, const struct wg_ return true; }
+static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_format *format) +{ + VIDEOINFO *video_format; + uint32_t frame_time; + const GUID *subtype; + + if (!(video_format = CoTaskMemAlloc(sizeof(*video_format)))) + return false; + + switch (format->u.video_wmv.version) + { + case 1: + subtype = &MEDIASUBTYPE_WMV1; + break; + case 2: + subtype = &MEDIASUBTYPE_WMV2; + break; + case 3: + subtype = &MEDIASUBTYPE_WMV3; + break; + default: + WARN("Invalid wmvversion %u.\n", format->u.video_wmv.version); + return false; + } + + mt->majortype = MEDIATYPE_Video; + mt->subtype = *subtype; + mt->bTemporalCompression = TRUE; + mt->lSampleSize = 1; + mt->formattype = FORMAT_VideoInfo; + mt->cbFormat = sizeof(VIDEOINFOHEADER); + mt->pbFormat = (BYTE *)video_format; + + memset(video_format, 0, sizeof(*video_format)); + SetRect(&video_format->rcSource, 0, 0, format->u.video_wmv.width, format->u.video_wmv.height); + video_format->rcTarget = video_format->rcSource; + if ((frame_time = MulDiv(10000000, format->u.video_wmv.fps_d, format->u.video_wmv.fps_n)) != -1) + video_format->AvgTimePerFrame = frame_time; + video_format->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + video_format->bmiHeader.biWidth = format->u.video_wmv.width; + video_format->bmiHeader.biHeight = format->u.video_wmv.height; + video_format->bmiHeader.biPlanes = 1; + video_format->bmiHeader.biBitCount = 24; + video_format->bmiHeader.biCompression = mt->subtype.Data1; + + return true; +} + bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool wm) { memset(mt, 0, sizeof(*mt)); @@ -547,7 +595,6 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_WMV: FIXME("Format %u not implemented!\n", format->major_type); /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: @@ -564,6 +611,9 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool
case WG_MAJOR_TYPE_VIDEO_CINEPAK: return amt_from_wg_format_video_cinepak(mt, format); + + case WG_MAJOR_TYPE_VIDEO_WMV: + return amt_from_wg_format_video_wmv(mt, format); }
assert(0); diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index a7876977d6c..1dac5085781 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -232,6 +232,40 @@ static void wg_format_from_caps_video_cinepak(struct wg_format *format, const Gs format->u.video_cinepak.fps_d = fps_d; }
+static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCaps *caps) +{ + const GstStructure *structure = gst_caps_get_structure(caps, 0); + gint width, height, fps_n, fps_d, version; + + if (!gst_structure_get_int(structure, "width", &width)) + { + GST_WARNING("Missing "width" value."); + return; + } + if (!gst_structure_get_int(structure, "height", &height)) + { + GST_WARNING("Missing "height" value."); + return; + } + if (!gst_structure_get_int(structure, "wmvversion", &version)) + { + GST_WARNING("Missing "wmvversion" value."); + return; + } + if (!gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d)) + { + fps_n = 0; + fps_d = 1; + } + + format->major_type = WG_MAJOR_TYPE_VIDEO_WMV; + format->u.video_wmv.width = width; + format->u.video_wmv.height = height; + format->u.video_wmv.version = version; + format->u.video_wmv.fps_n = fps_n; + format->u.video_wmv.fps_d = fps_d; +} + void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) { const GstStructure *structure = gst_caps_get_structure(caps, 0); @@ -261,6 +295,10 @@ void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) { wg_format_from_caps_video_cinepak(format, caps); } + else if (!strcmp(name, "video/x-wmv")) + { + wg_format_from_caps_video_wmv(format, caps); + } else { gchar *str = gst_caps_to_string(caps); @@ -611,7 +649,6 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_WMV: GST_FIXME("Format %u not implemented!", a->major_type); /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: @@ -633,6 +670,11 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) /* Do not compare FPS. */ return a->u.video_cinepak.width == b->u.video_cinepak.width && a->u.video_cinepak.height == b->u.video_cinepak.height; + + case WG_MAJOR_TYPE_VIDEO_WMV: + return a->u.video_wmv.width == b->u.video_wmv.width + && a->u.video_wmv.height == b->u.video_wmv.height + && a->u.video_wmv.version == b->u.video_wmv.version; }
assert(0); diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 18b0e8a90bc..278a8dae995 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -546,12 +546,20 @@ static HRESULT WINAPI stream_props_GetMediaType(IWMMediaProps *iface, WM_MEDIA_T struct stream_config *config = impl_from_IWMMediaProps(iface); const DWORD req_size = *size; AM_MEDIA_TYPE stream_mt; + struct wg_format format;
TRACE("iface %p, mt %p, size %p.\n", iface, mt, size);
- if (!amt_from_wg_format(&stream_mt, &config->stream->format, true)) + wg_parser_stream_get_preferred_format(config->stream->wg_stream, &format); + if (!amt_from_wg_format(&stream_mt, &format, true)) return E_OUTOFMEMORY;
+ /* Debug usage, will be removed when patch is submitted to upstream. + * According to tests, for WMV1 video, preferred_format is still RGB24, which is expected to be WMV1 here. + * So, how to get stream real format when using wmreader to read a compressed stream ? + * For example, I'd like get WMV3 format if I use wmreader to read a WMV3 stream. */ + WINE_MESSAGE("==== format.major_type %d, format.u.video.format %d.\n", format.major_type, format.u.video.format); + *size = sizeof(stream_mt) + stream_mt.cbFormat; if (!mt) return S_OK;