Commit 6c11a4af authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

winegstreamer: Move flipping based on RGB to the frontends.

Give the backend a more simple and self-consistent API. This commit also changes behaviour, by virtue of *not* changing some frontends. In specific, this commit does not modify the AVI splitter, which is known to output top-down RGB samples on Windows if the original video uses them (this is trivial to test by modifying test.avi in quartz to use "bgra" instead of "yuv420p"). It also does not modify the Media Foundation color converter DMO, whose tests imply that the MF_MT_DEFAULT_STRIDE attribute is always positive.
parent af82c44e
......@@ -527,8 +527,6 @@ static IMFMediaType *mf_media_type_from_wg_format_video(const struct wg_format *
IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
IMFMediaType_SetUINT32(type, &MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0);
if (wg_video_format_is_rgb(format->u.video.format))
stride = -stride;
if (format->u.video.height < 0)
stride = -stride;
IMFMediaType_SetUINT32(type, &MF_MT_DEFAULT_STRIDE, stride);
......@@ -732,11 +730,13 @@ static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *sub
if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_DEFAULT_STRIDE, &stride)))
{
if (wg_video_format_is_rgb(format->u.video.format))
format->u.video.height = -format->u.video.height;
if ((int)stride < 0)
format->u.video.height = -format->u.video.height;
}
else if (wg_video_format_is_rgb(format->u.video.format))
{
format->u.video.height = -format->u.video.height;
}
}
static void mf_media_type_to_wg_format_audio_wma(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
......
......@@ -485,7 +485,7 @@ static bool amt_from_wg_format_video(AM_MEDIA_TYPE *mt, const struct wg_format *
if (wm)
{
SetRect(&video_format->rcSource, 0, 0, format->u.video.width, format->u.video.height);
SetRect(&video_format->rcSource, 0, 0, format->u.video.width, abs(format->u.video.height));
video_format->rcTarget = video_format->rcSource;
}
if ((frame_time = MulDiv(10000000, format->u.video.fps_d, format->u.video.fps_n)) != -1)
......@@ -493,6 +493,8 @@ static bool amt_from_wg_format_video(AM_MEDIA_TYPE *mt, const struct wg_format *
video_format->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
video_format->bmiHeader.biWidth = format->u.video.width;
video_format->bmiHeader.biHeight = format->u.video.height;
if (wg_video_format_is_rgb(format->u.video.format))
video_format->bmiHeader.biHeight = -format->u.video.height;
video_format->bmiHeader.biPlanes = 1;
video_format->bmiHeader.biBitCount = wg_video_format_get_depth(format->u.video.format);
video_format->bmiHeader.biCompression = wg_video_format_get_compression(format->u.video.format);
......@@ -733,6 +735,8 @@ static bool amt_to_wg_format_video(const AM_MEDIA_TYPE *mt, struct wg_format *fo
if (IsEqualGUID(&mt->subtype, format_map[i].subtype))
{
format->u.video.format = format_map[i].format;
if (wg_video_format_is_rgb(format->u.video.format))
format->u.video.height = -format->u.video.height;
return true;
}
}
......@@ -1366,6 +1370,9 @@ static HRESULT decodebin_parser_source_get_media_type(struct parser_source *pin,
if (format.major_type == WG_MAJOR_TYPE_VIDEO && index < ARRAY_SIZE(video_formats))
{
format.u.video.format = video_formats[index];
/* Downstream filters probably expect RGB video to be bottom-up. */
if (format.u.video.height > 0 && wg_video_format_is_rgb(video_formats[index]))
format.u.video.height = -format.u.video.height;
if (!amt_from_wg_format(mt, &format, false))
return E_OUTOFMEMORY;
return S_OK;
......
......@@ -110,6 +110,8 @@ struct wg_format
WG_VIDEO_FORMAT_YV12,
WG_VIDEO_FORMAT_YVYU,
} format;
/* Positive height indicates top-down video; negative height
* indicates bottom-up video. */
int32_t width, height;
uint32_t fps_n, fps_d;
RECT padding;
......
......@@ -226,27 +226,6 @@ static NTSTATUS wg_parser_stream_enable(void *args)
{
bool flip = (format->u.video.height < 0);
switch (format->u.video.format)
{
case WG_VIDEO_FORMAT_BGRA:
case WG_VIDEO_FORMAT_BGRx:
case WG_VIDEO_FORMAT_BGR:
case WG_VIDEO_FORMAT_RGB15:
case WG_VIDEO_FORMAT_RGB16:
flip = !flip;
break;
case WG_VIDEO_FORMAT_AYUV:
case WG_VIDEO_FORMAT_I420:
case WG_VIDEO_FORMAT_NV12:
case WG_VIDEO_FORMAT_UYVY:
case WG_VIDEO_FORMAT_YUY2:
case WG_VIDEO_FORMAT_YV12:
case WG_VIDEO_FORMAT_YVYU:
case WG_VIDEO_FORMAT_UNKNOWN:
break;
}
gst_util_set_object_arg(G_OBJECT(stream->flip), "method", flip ? "vertical-flip" : "none");
}
......
......@@ -1508,6 +1508,10 @@ static HRESULT init_stream(struct wm_reader *reader, QWORD file_size)
* Shadowgrounds provides wmv3 video and assumes that the initial
* video type will be BGR. */
stream->format.u.video.format = WG_VIDEO_FORMAT_BGR;
/* API consumers expect RGB video to be bottom-up. */
if (stream->format.u.video.height > 0)
stream->format.u.video.height = -stream->format.u.video.height;
}
wg_parser_stream_enable(stream->wg_stream, &stream->format);
}
......@@ -1919,6 +1923,9 @@ static HRESULT WINAPI reader_GetOutputFormat(IWMSyncReader2 *iface,
return NS_E_INVALID_OUTPUT_FORMAT;
}
format.u.video.format = video_formats[index];
/* API consumers expect RGB video to be bottom-up. */
if (format.u.video.height > 0 && wg_video_format_is_rgb(format.u.video.format))
format.u.video.height = -format.u.video.height;
break;
case WG_MAJOR_TYPE_AUDIO:
......@@ -2211,7 +2218,7 @@ static HRESULT WINAPI reader_SetOutputProps(IWMSyncReader2 *iface, DWORD output,
hr = NS_E_INVALID_OUTPUT_FORMAT;
else if (pref_format.u.video.width != format.u.video.width)
hr = NS_E_INVALID_OUTPUT_FORMAT;
else if (pref_format.u.video.height != format.u.video.height)
else if (abs(pref_format.u.video.height) != abs(format.u.video.height))
hr = NS_E_INVALID_OUTPUT_FORMAT;
break;
......
......@@ -446,7 +446,7 @@ static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD inde
return DMO_E_TYPE_NOT_SET;
width = decoder->input_format.u.video_wmv.width;
height = decoder->input_format.u.video_wmv.height;
height = abs(decoder->input_format.u.video_wmv.height);
subtype = wmv_decoder_output_types[type_index].subtype;
if (FAILED(hr = MFCalculateImageSize(subtype, width, height, &image_size)))
{
......@@ -632,7 +632,7 @@ static HRESULT WINAPI media_object_GetOutputSizeInfo(IMediaObject *iface, DWORD
return DMO_E_TYPE_NOT_SET;
if (FAILED(hr = MFCalculateImageSize(&decoder->output_subtype,
decoder->output_format.u.video.width, decoder->output_format.u.video.height, (UINT32 *)size)))
decoder->output_format.u.video.width, abs(decoder->output_format.u.video.height), (UINT32 *)size)))
{
FIXME("Failed to get image size of subtype %s.\n", debugstr_guid(&decoder->output_subtype));
return hr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment