From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/quartz_parser.c | 12 ++++++++++-- dlls/winegstreamer/unixlib.h | 2 ++ dlls/winegstreamer/wg_format.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 381b2837214..b56e56c0483 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -558,7 +558,7 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form uint32_t frame_time; const GUID *subtype;
- if (!(video_format = CoTaskMemAlloc(sizeof(*video_format)))) + if (!(video_format = CoTaskMemAlloc(sizeof(*video_format) + format->u.video_wmv.codec_data_len))) return false;
switch (format->u.video_wmv.format) @@ -589,7 +589,7 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form mt->bTemporalCompression = TRUE; mt->lSampleSize = 0; mt->formattype = FORMAT_VideoInfo; - mt->cbFormat = sizeof(*video_format); + mt->cbFormat = sizeof(*video_format) + format->u.video_wmv.codec_data_len; mt->pbFormat = (BYTE *)video_format;
memset(video_format, 0, sizeof(*video_format)); @@ -602,6 +602,7 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form video_format->bmiHeader.biHeight = format->u.video_wmv.height; video_format->bmiHeader.biPlanes = 1; video_format->bmiHeader.biCompression = mt->subtype.Data1; + memcpy(video_format+1, format->u.video_wmv.codec_data, format->u.video_wmv.codec_data_len);
return true; } @@ -879,6 +880,13 @@ static bool amt_to_wg_format_video_wmv(const AM_MEDIA_TYPE *mt, struct wg_format else format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_UNKNOWN;
+ format->u.video_wmv.codec_data_len = mt->cbFormat - sizeof(VIDEOINFOHEADER); + if (format->u.video_wmv.codec_data_len > 64) + { + WARN("Too big codec_data value (%u).\n", (unsigned)format->u.video_wmv.codec_data_len); + format->u.video_wmv.codec_data_len = 0; + } + memcpy(format->u.video_wmv.codec_data, video_format+1, format->u.video_wmv.codec_data_len); return true; }
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 6c0c61f76bb..42cc853c4d0 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -157,6 +157,8 @@ struct wg_format wg_wmv_video_format format; int32_t width, height; uint32_t fps_n, fps_d; + uint32_t codec_data_len; + unsigned char codec_data[64]; } video_wmv; struct { diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 7d4bc7a5f8c..a48de3160ed 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -236,6 +236,9 @@ static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCap gchar format_buffer[5] = {'W','M','V','0',0}; enum wg_wmv_video_format wmv_format; const gchar *wmv_format_str = NULL; + const GValue *codec_data_value; + GstBuffer *codec_data; + GstMapInfo map;
if (!gst_structure_get_int(structure, "width", &width)) { @@ -280,6 +283,18 @@ static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCap format->u.video_wmv.format = wmv_format; format->u.video_wmv.fps_n = fps_n; format->u.video_wmv.fps_d = fps_d; + + if ((codec_data_value = gst_structure_get_value(structure, "codec_data")) && (codec_data = gst_value_get_buffer(codec_data_value))) + { + gst_buffer_map(codec_data, &map, GST_MAP_READ); + if (map.size <= 64) + { + format->u.video_wmv.codec_data_len = map.size; + memcpy(format->u.video_wmv.codec_data, map.data, map.size); + } + else GST_WARNING("Too big codec_data value (%u) in %" GST_PTR_FORMAT ".", (unsigned)map.size, caps); + gst_buffer_unmap(codec_data, &map); + } }
static void wg_format_from_caps_video_mpeg1(struct wg_format *format, const GstCaps *caps) @@ -665,6 +680,7 @@ static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format) { unsigned int wmv_version; const char *wmv_format; + GstBuffer *buffer; GstCaps *caps;
if (!(caps = gst_caps_new_empty_simple("video/x-wmv"))) @@ -712,6 +728,19 @@ static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format) if (format->u.video_wmv.fps_d || format->u.video_wmv.fps_n) gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_wmv.fps_n, format->u.video_wmv.fps_d, NULL);
+ if (format->u.video_wmv.codec_data_len) + { + if (!(buffer = gst_buffer_new_and_alloc(format->u.video_h264.codec_data_len))) + { + gst_caps_unref(caps); + return NULL; + } + + gst_buffer_fill(buffer, 0, format->u.video_wmv.codec_data, format->u.video_wmv.codec_data_len); + gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); + gst_buffer_unref(buffer); + } + return caps; }