Gstreamer stores the first component in the most significant bits, same as DirectShow.
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/winegstreamer/gstdemux.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index acb15dc9238..5b5add409c7 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -194,11 +194,11 @@ static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE amt->subtype = MEDIASUBTYPE_RGB24; bih->biBitCount = 24; break; - case GST_VIDEO_FORMAT_BGR16: + case GST_VIDEO_FORMAT_RGB16: amt->subtype = MEDIASUBTYPE_RGB565; bih->biBitCount = 16; break; - case GST_VIDEO_FORMAT_BGR15: + case GST_VIDEO_FORMAT_RGB15: amt->subtype = MEDIASUBTYPE_RGB555; bih->biBitCount = 16; break; @@ -380,8 +380,8 @@ static GstCaps *amt_to_gst_caps_video(const AM_MEDIA_TYPE *mt) {&MEDIASUBTYPE_ARGB32, GST_VIDEO_FORMAT_BGRA}, {&MEDIASUBTYPE_RGB32, GST_VIDEO_FORMAT_BGRx}, {&MEDIASUBTYPE_RGB24, GST_VIDEO_FORMAT_BGR}, - {&MEDIASUBTYPE_RGB565, GST_VIDEO_FORMAT_BGR16}, - {&MEDIASUBTYPE_RGB555, GST_VIDEO_FORMAT_BGR15}, + {&MEDIASUBTYPE_RGB565, GST_VIDEO_FORMAT_RGB16}, + {&MEDIASUBTYPE_RGB555, GST_VIDEO_FORMAT_RGB15}, };
const VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)mt->pbFormat;
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/winegstreamer/gstdemux.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 5b5add409c7..e95205ca44a 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -158,7 +158,7 @@ static gboolean amt_from_gst_audio_info(const GstAudioInfo *info, AM_MEDIA_TYPE
static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE *amt) { - VIDEOINFOHEADER *vih; + VIDEOINFO *vih; BITMAPINFOHEADER *bih; gint32 width, height;
@@ -170,7 +170,7 @@ static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE
amt->formattype = FORMAT_VideoInfo; amt->pbFormat = (BYTE*)vih; - amt->cbFormat = sizeof(*vih); + amt->cbFormat = sizeof(VIDEOINFOHEADER); amt->bFixedSizeSamples = FALSE; amt->bTemporalCompression = TRUE; amt->lSampleSize = 1; @@ -180,6 +180,7 @@ static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE
if (GST_VIDEO_INFO_IS_RGB(info)) { + bih->biCompression = BI_RGB; switch (GST_VIDEO_INFO_FORMAT(info)) { case GST_VIDEO_FORMAT_BGRA: @@ -196,7 +197,12 @@ static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE break; case GST_VIDEO_FORMAT_RGB16: amt->subtype = MEDIASUBTYPE_RGB565; + amt->cbFormat = offsetof(VIDEOINFO, u.dwBitMasks[3]); + vih->u.dwBitMasks[iRED] = 0xf800; + vih->u.dwBitMasks[iGREEN] = 0x07e0; + vih->u.dwBitMasks[iBLUE] = 0x001f; bih->biBitCount = 16; + bih->biCompression = BI_BITFIELDS; break; case GST_VIDEO_FORMAT_RGB15: amt->subtype = MEDIASUBTYPE_RGB555; @@ -207,7 +213,6 @@ static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE CoTaskMemFree(vih); return FALSE; } - bih->biCompression = BI_RGB; } else { amt->subtype = MEDIATYPE_Video; if (!(amt->subtype.Data1 = gst_video_format_to_fourcc(GST_VIDEO_INFO_FORMAT(info)))) @@ -2116,7 +2121,8 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface, buffer_size = format->bmiHeader.biSizeImage;
gst_util_set_object_arg(G_OBJECT(pin->flip), "method", - format->bmiHeader.biCompression == BI_RGB ? "vertical-flip" : "none"); + (format->bmiHeader.biCompression == BI_RGB + || format->bmiHeader.biCompression == BI_BITFIELDS) ? "vertical-flip" : "none"); } else if (IsEqualGUID(&pin->pin.pin.mt.formattype, &FORMAT_WaveFormatEx) && (IsEqualGUID(&pin->pin.pin.mt.subtype, &MEDIASUBTYPE_PCM)
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/winegstreamer/gstdemux.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index e95205ca44a..90a129f29a4 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -1003,7 +1003,7 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux *
if (!strcmp(typename, "video/x-raw")) { - GstElement *vconv, *flip, *deinterlace; + GstElement *deinterlace, *vconv, *flip, *vconv2;
/* DirectShow can express interlaced video, but downstream filters can't * necessarily consume it. In particular, the video renderer can't. */ @@ -1035,6 +1035,18 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux * goto out; }
+ /* videoflip does not support 15 and 16-bit RGB so add a second videoconvert + * to do the final conversion. */ + if (!(vconv2 = gst_element_factory_make("videoconvert", NULL))) + { + ERR("Failed to create videoconvert, are %u-bit GStreamer "base" plugins installed?\n", + 8 * (int)sizeof(void *)); + goto out; + } + + /* Avoid expensive color matrix conversions. */ + gst_util_set_object_arg(G_OBJECT(vconv2), "matrix-mode", "none"); + /* The bin takes ownership of these elements. */ gst_bin_add(GST_BIN(This->container), deinterlace); gst_element_sync_state_with_parent(deinterlace); @@ -1042,12 +1054,15 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux * gst_element_sync_state_with_parent(vconv); gst_bin_add(GST_BIN(This->container), flip); gst_element_sync_state_with_parent(flip); + gst_bin_add(GST_BIN(This->container), vconv2); + gst_element_sync_state_with_parent(vconv2);
gst_element_link(deinterlace, vconv); gst_element_link(vconv, flip); + gst_element_link(flip, vconv2);
pin->post_sink = gst_element_get_static_pad(deinterlace, "sink"); - pin->post_src = gst_element_get_static_pad(flip, "src"); + pin->post_src = gst_element_get_static_pad(vconv2, "src"); pin->flip = flip; } else if (!strcmp(typename, "audio/x-raw"))
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/winegstreamer/gstdemux.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 90a129f29a4..6279c2c28c0 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -1722,6 +1722,8 @@ static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin, GST_VIDEO_FORMAT_BGRA, GST_VIDEO_FORMAT_BGRx, GST_VIDEO_FORMAT_BGR, + GST_VIDEO_FORMAT_RGB16, + GST_VIDEO_FORMAT_RGB15, };
assert(caps); /* We shouldn't be able to get here if caps haven't been set. */
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 4 ++++ dlls/amstream/tests/amstream.c | 2 ++ 2 files changed, 6 insertions(+)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 6ea99d4915e..509e489435b 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -69,6 +69,7 @@ struct ddraw_sample { IDirectDrawStreamSample IDirectDrawStreamSample_iface; LONG ref; + IMultiMediaStream *mmstream; struct ddraw_stream *parent; IDirectDrawSurface *surface; RECT rect; @@ -1462,6 +1463,8 @@ static ULONG WINAPI ddraw_sample_Release(IDirectDrawStreamSample *iface) --sample->parent->sample_refs; LeaveCriticalSection(&sample->parent->cs);
+ if (sample->mmstream) + IMultiMediaStream_Release(sample->mmstream); IAMMediaStream_Release(&sample->parent->IAMMediaStream_iface);
if (sample->surface) @@ -1680,6 +1683,7 @@ static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDraw object->parent = parent; InitializeConditionVariable(&object->update_cv); IAMMediaStream_AddRef(&parent->IAMMediaStream_iface); + IAMMediaStream_GetMultiMediaStream(&parent->IAMMediaStream_iface, &object->mmstream); ++parent->sample_refs;
if (surface) diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 285dc0f0547..9dda5882a4f 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -6904,9 +6904,11 @@ static void test_ddrawstream_create_sample(void) hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, &rect, 0, &sample); ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ EXPECT_REF(mmstream, 1); EXPECT_REF(stream, 3); hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample); ok(hr == S_OK, "Got hr %#x.\n", hr); + EXPECT_REF(mmstream, 2); EXPECT_REF(stream, 4);
hr = IDirectDrawStreamSample_GetSurface(sample, NULL, NULL);
On 10/6/20 1:05 PM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 4 ++++ dlls/amstream/tests/amstream.c | 2 ++ 2 files changed, 6 insertions(+)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 6ea99d4915e..509e489435b 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -69,6 +69,7 @@ struct ddraw_sample { IDirectDrawStreamSample IDirectDrawStreamSample_iface; LONG ref;
- IMultiMediaStream *mmstream; struct ddraw_stream *parent; IDirectDrawSurface *surface; RECT rect;
@@ -1462,6 +1463,8 @@ static ULONG WINAPI ddraw_sample_Release(IDirectDrawStreamSample *iface) --sample->parent->sample_refs; LeaveCriticalSection(&sample->parent->cs);
if (sample->mmstream)
IMultiMediaStream_Release(sample->mmstream); IAMMediaStream_Release(&sample->parent->IAMMediaStream_iface); if (sample->surface)
@@ -1680,6 +1683,7 @@ static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDraw object->parent = parent; InitializeConditionVariable(&object->update_cv); IAMMediaStream_AddRef(&parent->IAMMediaStream_iface);
- IAMMediaStream_GetMultiMediaStream(&parent->IAMMediaStream_iface, &object->mmstream);
I think I would prefer accessing parent->parent directly; it's another two lines of code but avoids extra trace lines.
++parent->sample_refs; if (surface)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 285dc0f0547..9dda5882a4f 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -6904,9 +6904,11 @@ static void test_ddrawstream_create_sample(void) hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, &rect, 0, &sample); ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
EXPECT_REF(mmstream, 1); EXPECT_REF(stream, 3); hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample); ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(mmstream, 2); EXPECT_REF(stream, 4);
hr = IDirectDrawStreamSample_GetSurface(sample, NULL, NULL);