From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/mfplat.c | 1 + dlls/winegstreamer/quartz_parser.c | 49 ++++++++++++++++++++++++------ dlls/winegstreamer/unixlib.h | 10 ++++-- dlls/winegstreamer/wg_format.c | 35 +++++++++++++++++---- dlls/winegstreamer/wg_parser.c | 1 - dlls/winegstreamer/wg_transform.c | 2 ++ dlls/winegstreamer/wm_reader.c | 4 +++ 7 files changed, 83 insertions(+), 19 deletions(-)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index d6620c0d08a..7c58ed93bfd 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -490,6 +490,7 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) case WG_MAJOR_TYPE_H264: case WG_MAJOR_TYPE_WMA: case WG_MAJOR_TYPE_MPEG1_AUDIO: + case WG_MAJOR_TYPE_VIDEO_CINEPAK: FIXME("Format %u not implemented!\n", format->major_type); /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 1ba24580cf6..12091d75398 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -300,12 +300,6 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) return ALIGN(width, 4) * ALIGN(height, 2) /* Y plane */ + ALIGN(width, 4) * ((height + 1) / 2); /* U/V plane */
- case WG_VIDEO_FORMAT_CINEPAK: - /* Both ffmpeg's encoder and a Cinepak file seen in the wild report - * 24 bpp. ffmpeg sets biSizeImage as below; others may be smaller, - * but as long as every sample fits into our allocator, we're fine. */ - return width * height * 3; - case WG_VIDEO_FORMAT_UNKNOWN: FIXME("Cannot guess maximum sample size for unknown video format.\n"); return 0; @@ -313,6 +307,12 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) break; }
+ case WG_MAJOR_TYPE_VIDEO_CINEPAK: + /* Both ffmpeg's encoder and a Cinepak file seen in the wild report + * 24 bpp. ffmpeg sets biSizeImage as below; others may be smaller, + * but as long as every sample fits into our allocator, we're fine. */ + return format->u.video_cinepak.width * format->u.video_cinepak.height * 3; + case WG_MAJOR_TYPE_AUDIO: { unsigned int rate = format->u.audio.rate, channels = format->u.audio.channels; @@ -390,7 +390,6 @@ static const GUID *wg_video_format_get_mediasubtype(enum wg_video_format format) case WG_VIDEO_FORMAT_YUY2: return &MEDIASUBTYPE_YUY2; case WG_VIDEO_FORMAT_YV12: return &MEDIASUBTYPE_YV12; case WG_VIDEO_FORMAT_YVYU: return &MEDIASUBTYPE_YVYU; - case WG_VIDEO_FORMAT_CINEPAK: return &MEDIASUBTYPE_CVID; }
assert(0); @@ -414,7 +413,6 @@ static DWORD wg_video_format_get_compression(enum wg_video_format format) case WG_VIDEO_FORMAT_YUY2: return mmioFOURCC('Y','U','Y','2'); case WG_VIDEO_FORMAT_YV12: return mmioFOURCC('Y','V','1','2'); case WG_VIDEO_FORMAT_YVYU: return mmioFOURCC('Y','V','Y','U'); - case WG_VIDEO_FORMAT_CINEPAK: return mmioFOURCC('C','V','I','D'); }
assert(0); @@ -438,7 +436,6 @@ static WORD wg_video_format_get_depth(enum wg_video_format format) case WG_VIDEO_FORMAT_YUY2: return 16; case WG_VIDEO_FORMAT_YV12: return 12; case WG_VIDEO_FORMAT_YVYU: return 16; - case WG_VIDEO_FORMAT_CINEPAK: return 24; }
assert(0); @@ -495,6 +492,36 @@ static bool amt_from_wg_format_video(AM_MEDIA_TYPE *mt, const struct wg_format * return true; }
+static bool amt_from_wg_format_video_cinepak(AM_MEDIA_TYPE *mt, const struct wg_format *format) +{ + VIDEOINFO *video_format; + uint32_t frame_time; + + if (!(video_format = CoTaskMemAlloc(sizeof(*video_format)))) + return false; + + mt->majortype = MEDIATYPE_Video; + mt->subtype = MEDIASUBTYPE_CVID; + 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)); + if ((frame_time = MulDiv(10000000, format->u.video_cinepak.fps_d, format->u.video_cinepak.fps_n)) != -1) + video_format->AvgTimePerFrame = frame_time; + video_format->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + video_format->bmiHeader.biWidth = format->u.video_cinepak.width; + video_format->bmiHeader.biHeight = format->u.video_cinepak.height; + video_format->bmiHeader.biPlanes = 1; + video_format->bmiHeader.biBitCount = 24; + video_format->bmiHeader.biCompression = mt->subtype.Data1; + video_format->bmiHeader.biSizeImage = wg_format_get_max_size(format); + + return true; +} + bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool wm) { memset(mt, 0, sizeof(*mt)); @@ -516,6 +543,9 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool
case WG_MAJOR_TYPE_VIDEO: return amt_from_wg_format_video(mt, format, wm); + + case WG_MAJOR_TYPE_VIDEO_CINEPAK: + return amt_from_wg_format_video_cinepak(mt, format); }
assert(0); @@ -656,7 +686,6 @@ static bool amt_to_wg_format_video(const AM_MEDIA_TYPE *mt, struct wg_format *fo {&MEDIASUBTYPE_YUY2, WG_VIDEO_FORMAT_YUY2}, {&MEDIASUBTYPE_YV12, WG_VIDEO_FORMAT_YV12}, {&MEDIASUBTYPE_YVYU, WG_VIDEO_FORMAT_YVYU}, - {&MEDIASUBTYPE_CVID, WG_VIDEO_FORMAT_CINEPAK}, };
const VIDEOINFOHEADER *video_format = (const VIDEOINFOHEADER *)mt->pbFormat; diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index e2eef2a4932..5692b0e6f11 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -36,6 +36,7 @@ struct wg_format { WG_MAJOR_TYPE_UNKNOWN, WG_MAJOR_TYPE_VIDEO, + WG_MAJOR_TYPE_VIDEO_CINEPAK, WG_MAJOR_TYPE_AUDIO, WG_MAJOR_TYPE_MPEG1_AUDIO, WG_MAJOR_TYPE_WMA, @@ -63,8 +64,6 @@ struct wg_format WG_VIDEO_FORMAT_YUY2, WG_VIDEO_FORMAT_YV12, WG_VIDEO_FORMAT_YVYU, - - WG_VIDEO_FORMAT_CINEPAK, } format; int32_t width, height; uint32_t fps_n, fps_d; @@ -106,6 +105,13 @@ struct wg_format unsigned char codec_data[64]; } wma; struct + { + uint32_t width; + uint32_t height; + uint32_t fps_n; + uint32_t fps_d; + } video_cinepak; + struct { int32_t width, height; uint32_t fps_n, fps_d; diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 3b568ea2fec..5f87163cb72 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -225,12 +225,11 @@ static void wg_format_from_caps_video_cinepak(struct wg_format *format, const Gs fps_d = 1; }
- format->major_type = WG_MAJOR_TYPE_VIDEO; - format->u.video.format = WG_VIDEO_FORMAT_CINEPAK; - format->u.video.width = width; - format->u.video.height = height; - format->u.video.fps_n = fps_n; - format->u.video.fps_d = fps_d; + format->major_type = WG_MAJOR_TYPE_VIDEO_CINEPAK; + format->u.video_cinepak.width = width; + format->u.video_cinepak.height = height; + format->u.video_cinepak.fps_n = fps_n; + format->u.video_cinepak.fps_d = fps_d; }
void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) @@ -407,6 +406,23 @@ static GstCaps *wg_format_to_caps_video(const struct wg_format *format) return caps; }
+static GstCaps *wg_format_to_caps_video_cinepak(const struct wg_format *format) +{ + GstCaps *caps; + + if (!(caps = gst_caps_new_empty_simple("video/x-cinepak"))) + return NULL; + + if (format->u.video_cinepak.width) + gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_cinepak.width, NULL); + if (format->u.video_cinepak.height) + gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_cinepak.height, NULL); + if (format->u.video_cinepak.fps_d || format->u.video_cinepak.fps_n) + gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_cinepak.fps_n, format->u.video_cinepak.fps_d, NULL); + + return caps; +} + static GstCaps *wg_format_to_caps_wma(const struct wg_format *format) { GstBuffer *buffer; @@ -523,6 +539,8 @@ GstCaps *wg_format_to_caps(const struct wg_format *format) return wg_format_to_caps_audio(format); case WG_MAJOR_TYPE_VIDEO: return wg_format_to_caps_video(format); + case WG_MAJOR_TYPE_VIDEO_CINEPAK: + return wg_format_to_caps_video_cinepak(format); } assert(0); return NULL; @@ -554,6 +572,11 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) && a->u.video.width == b->u.video.width && abs(a->u.video.height) == abs(b->u.video.height) && EqualRect( &a->u.video.padding, &b->u.video.padding ); + + case WG_MAJOR_TYPE_VIDEO_CINEPAK: + /* 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; }
assert(0); diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index f0487fd1ffa..3e428cdebe8 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -236,7 +236,6 @@ static NTSTATUS wg_parser_stream_enable(void *args) case WG_VIDEO_FORMAT_YV12: case WG_VIDEO_FORMAT_YVYU: case WG_VIDEO_FORMAT_UNKNOWN: - case WG_VIDEO_FORMAT_CINEPAK: break; }
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index e703e93b07e..6fd3a097ed0 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -425,6 +425,7 @@ NTSTATUS wg_transform_create(void *args) /* fallthrough */ case WG_MAJOR_TYPE_MPEG1_AUDIO: case WG_MAJOR_TYPE_WMA: + case WG_MAJOR_TYPE_VIDEO_CINEPAK: if (!(element = transform_find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, src_caps, raw_caps)) || !transform_append_element(transform, element, &first, &last)) { @@ -475,6 +476,7 @@ NTSTATUS wg_transform_create(void *args) case WG_MAJOR_TYPE_MPEG1_AUDIO: case WG_MAJOR_TYPE_H264: case WG_MAJOR_TYPE_WMA: + case WG_MAJOR_TYPE_VIDEO_CINEPAK: case WG_MAJOR_TYPE_UNKNOWN: GST_FIXME("Format %u not implemented!", output_format.major_type); goto out; diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 95d6d8e0180..610338554f1 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -1511,6 +1511,8 @@ static const char *get_major_type_string(enum wg_major_type type) return "audio"; case WG_MAJOR_TYPE_VIDEO: return "video"; + case WG_MAJOR_TYPE_VIDEO_CINEPAK: + return "cinepak"; case WG_MAJOR_TYPE_UNKNOWN: return "unknown"; case WG_MAJOR_TYPE_MPEG1_AUDIO: @@ -1975,6 +1977,7 @@ static HRESULT WINAPI reader_GetOutputFormat(IWMSyncReader2 *iface, case WG_MAJOR_TYPE_MPEG1_AUDIO: case WG_MAJOR_TYPE_WMA: case WG_MAJOR_TYPE_H264: + case WG_MAJOR_TYPE_VIDEO_CINEPAK: FIXME("Format %u not implemented!\n", format.major_type); break; case WG_MAJOR_TYPE_UNKNOWN: @@ -2013,6 +2016,7 @@ static HRESULT WINAPI reader_GetOutputFormatCount(IWMSyncReader2 *iface, DWORD o case WG_MAJOR_TYPE_MPEG1_AUDIO: case WG_MAJOR_TYPE_WMA: case WG_MAJOR_TYPE_H264: + case WG_MAJOR_TYPE_VIDEO_CINEPAK: FIXME("Format %u not implemented!\n", format.major_type); /* fallthrough */ case WG_MAJOR_TYPE_AUDIO: