Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2022
- 68 participants
- 3274 messages
[PATCH v2 2/5] winegstreamer: Rename mf_(create|destroy)_wg_sample helpers.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winegstreamer/gst_private.h | 4 ++--
dlls/winegstreamer/h264_decoder.c | 10 +++++-----
dlls/winegstreamer/mfplat.c | 4 ++--
dlls/winegstreamer/wma_decoder.c | 12 ++++++------
4 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index ca7396ad5cd..ab89942847a 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -120,8 +120,8 @@ extern HRESULT mfplat_DllRegisterServer(void);
IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format);
void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format);
-HRESULT mf_create_wg_sample(IMFSample *sample, struct wg_sample **out);
-void mf_destroy_wg_sample(struct wg_sample *wg_sample);
+HRESULT wg_sample_create_mf(IMFSample *sample, struct wg_sample **out);
+void wg_sample_release(struct wg_sample *wg_sample);
HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *sample);
HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *sample,
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index 0ee9084e12e..8d3de4355bb 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -540,11 +540,11 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS
if (!decoder->wg_transform)
return MF_E_TRANSFORM_TYPE_NOT_SET;
- if (FAILED(hr = mf_create_wg_sample(sample, &wg_sample)))
+ if (FAILED(hr = wg_sample_create_mf(sample, &wg_sample)))
return hr;
hr = wg_transform_push_mf(decoder->wg_transform, wg_sample);
- mf_destroy_wg_sample(wg_sample);
+ wg_sample_release(wg_sample);
return hr;
}
@@ -573,17 +573,17 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
samples[0].dwStatus = 0;
if (!samples[0].pSample) return E_INVALIDARG;
- if (FAILED(hr = mf_create_wg_sample(samples[0].pSample, &wg_sample)))
+ if (FAILED(hr = wg_sample_create_mf(samples[0].pSample, &wg_sample)))
return hr;
if (wg_sample->max_size < info.cbSize)
{
- mf_destroy_wg_sample(wg_sample);
+ wg_sample_release(wg_sample);
return MF_E_BUFFERTOOSMALL;
}
hr = wg_transform_read_mf(decoder->wg_transform, wg_sample, &wg_format);
- mf_destroy_wg_sample(wg_sample);
+ wg_sample_release(wg_sample);
if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
{
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 026237bdf5d..28a3fc20ead 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -965,7 +965,7 @@ struct mf_sample
struct wg_sample wg_sample;
};
-HRESULT mf_create_wg_sample(IMFSample *sample, struct wg_sample **out)
+HRESULT wg_sample_create_mf(IMFSample *sample, struct wg_sample **out)
{
DWORD current_length, max_length;
struct mf_sample *mf_sample;
@@ -995,7 +995,7 @@ out:
return hr;
}
-void mf_destroy_wg_sample(struct wg_sample *wg_sample)
+void wg_sample_release(struct wg_sample *wg_sample)
{
struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index fdb68328c3a..81285f5ad44 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -534,18 +534,18 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS
if (FAILED(hr = IMFTransform_GetInputStreamInfo(iface, 0, &info)))
return hr;
- if (FAILED(hr = mf_create_wg_sample(sample, &wg_sample)))
+ if (FAILED(hr = wg_sample_create_mf(sample, &wg_sample)))
return hr;
/* WMA transform uses fixed size input samples and ignores samples with invalid sizes */
if (wg_sample->size % info.cbSize)
{
- mf_destroy_wg_sample(wg_sample);
+ wg_sample_release(wg_sample);
return S_OK;
}
hr = wg_transform_push_mf(decoder->wg_transform, wg_sample);
- mf_destroy_wg_sample(wg_sample);
+ wg_sample_release(wg_sample);
return hr;
}
@@ -576,13 +576,13 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
return MF_E_TRANSFORM_NEED_MORE_INPUT;
}
- if (FAILED(hr = mf_create_wg_sample(samples[0].pSample, &wg_sample)))
+ if (FAILED(hr = wg_sample_create_mf(samples[0].pSample, &wg_sample)))
return hr;
wg_sample->size = 0;
if (wg_sample->max_size < info.cbSize)
{
- mf_destroy_wg_sample(wg_sample);
+ wg_sample_release(wg_sample);
return MF_E_BUFFERTOOSMALL;
}
@@ -592,7 +592,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE;
}
- mf_destroy_wg_sample(wg_sample);
+ wg_sample_release(wg_sample);
if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
{
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/197
June 8, 2022
[PATCH v2 1/5] winegstreamer: Introduce new wg_transform_(push|read)_mf helpers.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
To read MF sample properties before pushing, and update them after
sucessfully reading a sample.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winegstreamer/gst_private.h | 4 +++
dlls/winegstreamer/h264_decoder.c | 6 ++--
dlls/winegstreamer/mfplat.c | 55 +++++++++++++++++++++----------
dlls/winegstreamer/wma_decoder.c | 4 +--
4 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 159143d7e54..ca7396ad5cd 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -123,6 +123,10 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format);
HRESULT mf_create_wg_sample(IMFSample *sample, struct wg_sample **out);
void mf_destroy_wg_sample(struct wg_sample *wg_sample);
+HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *sample);
+HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *sample,
+ struct wg_format *format);
+
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj);
HRESULT h264_decoder_create(REFIID riid, void **ret);
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index 19a36a9a77a..0ee9084e12e 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -543,8 +543,7 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS
if (FAILED(hr = mf_create_wg_sample(sample, &wg_sample)))
return hr;
- hr = wg_transform_push_data(decoder->wg_transform, wg_sample);
-
+ hr = wg_transform_push_mf(decoder->wg_transform, wg_sample);
mf_destroy_wg_sample(wg_sample);
return hr;
}
@@ -583,8 +582,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
return MF_E_BUFFERTOOSMALL;
}
- hr = wg_transform_read_data(decoder->wg_transform, wg_sample,
- &wg_format);
+ hr = wg_transform_read_mf(decoder->wg_transform, wg_sample, &wg_format);
mf_destroy_wg_sample(wg_sample);
if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 0226e7a2e45..026237bdf5d 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -969,8 +969,6 @@ HRESULT mf_create_wg_sample(IMFSample *sample, struct wg_sample **out)
{
DWORD current_length, max_length;
struct mf_sample *mf_sample;
- LONGLONG time, duration;
- UINT32 value;
BYTE *buffer;
HRESULT hr;
@@ -981,19 +979,6 @@ HRESULT mf_create_wg_sample(IMFSample *sample, struct wg_sample **out)
if (FAILED(hr = IMFMediaBuffer_Lock(mf_sample->media_buffer, &buffer, &max_length, ¤t_length)))
goto out;
- if (SUCCEEDED(IMFSample_GetSampleTime(sample, &time)))
- {
- mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
- mf_sample->wg_sample.pts = time;
- }
- if (SUCCEEDED(IMFSample_GetSampleDuration(sample, &duration)))
- {
- mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
- mf_sample->wg_sample.duration = duration;
- }
- if (SUCCEEDED(IMFSample_GetUINT32(sample, &MFSampleExtension_CleanPoint, &value)) && value)
- mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT;
-
IMFSample_AddRef((mf_sample->sample = sample));
mf_sample->wg_sample.data = buffer;
mf_sample->wg_sample.size = current_length;
@@ -1015,8 +1000,43 @@ void mf_destroy_wg_sample(struct wg_sample *wg_sample)
struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
IMFMediaBuffer_Unlock(mf_sample->media_buffer);
- IMFMediaBuffer_SetCurrentLength(mf_sample->media_buffer, wg_sample->size);
IMFMediaBuffer_Release(mf_sample->media_buffer);
+ IMFSample_Release(mf_sample->sample);
+ free(mf_sample);
+}
+
+HRESULT wg_transform_push_mf(struct wg_transform *transform, struct wg_sample *sample)
+{
+ struct mf_sample *mf_sample = CONTAINING_RECORD(sample, struct mf_sample, wg_sample);
+ LONGLONG time, duration;
+ UINT32 value;
+
+ if (SUCCEEDED(IMFSample_GetSampleTime(mf_sample->sample, &time)))
+ {
+ mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
+ mf_sample->wg_sample.pts = time;
+ }
+ if (SUCCEEDED(IMFSample_GetSampleDuration(mf_sample->sample, &duration)))
+ {
+ mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
+ mf_sample->wg_sample.duration = duration;
+ }
+ if (SUCCEEDED(IMFSample_GetUINT32(mf_sample->sample, &MFSampleExtension_CleanPoint, &value)) && value)
+ mf_sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT;
+
+ return wg_transform_push_data(transform, sample);
+}
+
+HRESULT wg_transform_read_mf(struct wg_transform *transform, struct wg_sample *wg_sample,
+ struct wg_format *format)
+{
+ struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
+ HRESULT hr;
+
+ if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format)))
+ return hr;
+
+ IMFMediaBuffer_SetCurrentLength(mf_sample->media_buffer, wg_sample->size);
if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS)
IMFSample_SetSampleTime(mf_sample->sample, wg_sample->pts);
@@ -1025,6 +1045,5 @@ void mf_destroy_wg_sample(struct wg_sample *wg_sample)
if (wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)
IMFSample_SetUINT32(mf_sample->sample, &MFSampleExtension_CleanPoint, 1);
- IMFSample_Release(mf_sample->sample);
- free(mf_sample);
+ return S_OK;
}
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 106d32adce9..fdb68328c3a 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -544,7 +544,7 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS
return S_OK;
}
- hr = wg_transform_push_data(decoder->wg_transform, wg_sample);
+ hr = wg_transform_push_mf(decoder->wg_transform, wg_sample);
mf_destroy_wg_sample(wg_sample);
return hr;
}
@@ -586,7 +586,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
return MF_E_BUFFERTOOSMALL;
}
- if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, wg_sample, NULL)))
+ if (SUCCEEDED(hr = wg_transform_read_mf(decoder->wg_transform, wg_sample, NULL)))
{
if (wg_sample->flags & WG_SAMPLE_FLAG_INCOMPLETE)
samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/197
June 8, 2022
[PATCH v2 0/5] MR197: winegstreamer: Add support for zero-copy in wg_transform.
by Rémi Bernon
--
v2: winegstreamer: Support zero-copy in wg_transform_push_data.
winegstreamer: Support zero-copy output using the allocator.
winegstreamer: Introduce a new custom memory allocator.
winegstreamer: Rename mf_(create|destroy)_wg_sample helpers.
winegstreamer: Introduce new wg_transform_(push|read)_mf helpers.
https://gitlab.winehq.org/wine/wine/-/merge_requests/197
June 8, 2022
Re: [PATCH 0/5] MR197: winegstreamer: Add support for zero-copy in wg_transform.
by Rémi Bernon
> (Maybe bring the incref/decref into the caller?)
I didn't want to because the queue append function is possibly going to be used in several places.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/197#note_1694
June 8, 2022
Re: [PATCH 6/6] uiautomationcore: Implement MSAA accState based property IDs for MSAA providers.
by Huw Davies
On Wed, May 25, 2022 at 02:37:39PM -0400, Connor McAdams wrote:
> static void test_UiaProviderFromIAccessible(void)
> diff --git a/dlls/uiautomationcore/uia_provider.c b/dlls/uiautomationcore/uia_provider.c
> index ab2b8305b10..69bc78e34c0 100644
> --- a/dlls/uiautomationcore/uia_provider.c
> +++ b/dlls/uiautomationcore/uia_provider.c
> @@ -32,6 +32,25 @@ static void variant_init_i4(VARIANT *v, int val)
> V_I4(v) = val;
> }
>
> +static void variant_init_bool(VARIANT *v, BOOL val)
> +{
> + V_VT(v) = VT_BOOL;
> + V_BOOL(v) = val ? VARIANT_TRUE : VARIANT_FALSE;
> +}
> +
> +static BOOL msaa_check_acc_state(IAccessible *acc, VARIANT cid, LONG flag)
DWORD/ULONG flag.
> +{
> + HRESULT hr;
> + VARIANT v;
> +
> + VariantInit(&v);
> + hr = IAccessible_get_accState(acc, cid, &v);
> + if (SUCCEEDED(hr) && V_VT(&v) == VT_I4 && (V_I4(&v) & flag))
> + return TRUE;
> +
> + return FALSE;
> +}
> +
> static LONG msaa_role_to_uia_control_type(LONG role)
> {
> switch (role)
> @@ -214,6 +233,26 @@ HRESULT WINAPI msaa_provider_GetPropertyValue(IRawElementProviderSimple *iface,
>
> break;
>
> + case UIA_HasKeyboardFocusPropertyId:
> + variant_init_bool(ret_val, msaa_check_acc_state(msaa_prov->acc, msaa_prov->cid,
> + STATE_SYSTEM_FOCUSED));
Unless you have need for these two helpers down the line, I'd combine
them, i.e. have _check_acc_state() return a VARIANT.
Huw.
P.S. bonus points will be awarded for using gitlab to send v2 ;-)
June 8, 2022
Re: [PATCH 2/6] uiautomationcore/tests: Skip UiaProviderFromIAccessible tests on Win10v1507.
by Huw Davies
On Tue, Jun 07, 2022 at 11:29:12AM -0400, Connor McAdams wrote:
> On Tue, Jun 07, 2022 at 04:13:45PM +0100, Huw Davies wrote:
> > On Tue, Jun 07, 2022 at 11:02:31AM -0400, Connor McAdams wrote:
> > > On Tue, Jun 07, 2022 at 10:07:22AM +0100, Huw Davies wrote:
> > > > On Wed, May 25, 2022 at 02:37:35PM -0400, Connor McAdams wrote:
> > > > > In Windows 10 version 1507, UiaProviderFromIAccessible will try to check
> > > > > the IAccessible passed in against the root IAccessible of the HWND
> > > > > associated with the passed in IAccessible. In all other Windows
> > > > > versions, this check is done on a call to get_HostRawElementProvider, or
> > > > > the first time navigating towards a parent or sibling. Rather than work
> > > > > around this, just skip the tests if this happens.
> > > >
> > > > Could we write the tests so that they don't rely on implementation
> > > > details? Presumably applications run correctly on Windows 10 v1507.
> > > >
> > > > Huw.
> > >
> > > So, essentially most of my tests for UI Automation kind of revolve
> > > around things like SET_EXPECT/CHECK_EXPECT/CHECK_CALLED tests as a way
> > > of testing what UI Automation does with the interfaces we pass into it.
> > > This is similar to how the tests for oleacc are done. In this case, we'd
> > > end up with a number of tests where we'd have to add a bunch of
> > > SET_EXPECT's to account for one specific version of Windows, then we'd
> > > need some sort of special CHECK_CALLED that could account for a broken
> > > behavior. It's a lot more work than I think it's worth to work around a
> > > bug in one specific version of Windows 10.
> >
> > Is it really a bug in Windows; it seems more like a different
> > implementation? How different are the call sequences?
>
> I believe it's a bug, or at least a behavior that was undesirable.
> All other versions of Windows seem to delay this root IAccessible check
> until specific methods are called on the IRawElementProviderSimple
> wrapper. The check is basically sending the HWND associated with an
> IAccessible a WM_GETOBJECT message, and then the returned IAccessible is
> compared against the currently wrapped one. This can end up with:
I'm still not convinced it's a bug or even undesirable behaviour; it's
just different. However, skipping here does allow some useful tests,
so I'll let it go and hope Windows doesn't change its implementation
again.
Huw.
June 8, 2022
Re: [PATCH 0/5] MR197: winegstreamer: Add support for zero-copy in wg_transform.
by Rémi Bernon
> >``` @@ -116,8 +160,15 @@ static GstMemory *wg_allocator_alloc(GstAllocator *gst_allocator, gsize size,
> > memory->unix_memory = gst_allocator_alloc(NULL, size, params);
> > gst_memory_map(memory->unix_memory, &memory->unix_map_info, GST_MAP_WRITE);
> >
> > - GST_INFO("Allocated memory %p, unix_memory %p, data %p", memory, memory->unix_memory,
> > - memory->unix_map_info.data);
> > + pthread_mutex_lock(&allocator->mutex);
> > +
> > + memory->sample = allocator->request_sample(size, allocator->request_sample_context);
> > + list_add_tail(&allocator->memory_list, &memory->entry);
> > +
> > + pthread_mutex_unlock(&allocator->mutex);
> > +
> > + GST_INFO("Allocated memory %p, sample %p, unix_memory %p, data %p", memory,
> > + memory->sample, memory->unix_memory, memory->unix_map_info.data);
> > return (GstMemory *)memory;
> > }
> >```
>
> Could we do this without the callback? Just thinking out loud, maybe
> something like
>
> void wg_allocator_add_sample(WgAllocator *allocator,
> struct wg_sample *sample);
> void wg_allocator_remove_sample(WgAllocator *allocator,
> struct wg_sample *sample);
>
> which manipulate an internal wg_sample pointer, instead of having them
> access the wg_transform's sample pointer. Then
> wg_allocator_remove_sample() would also end up calling
> wg_allocator_release_sample().
>
> I suspect I'm missing something, though, given my below comment...
The callback is with a future use from wg_parser in mind. In that case
we would forward allocation requests to the read thread (for instance).
> >``` if (!(sample->flags & WG_SAMPLE_FLAG_INCOMPLETE))
> > {
> > + /* Taint the buffer memory to make sure it cannot be reused by the buffer pool,
> > + * for the pool to always requests new memory from the allocator, and so we can
> > + * then always provide output sample memory to achieve zero-copy.
> > + *
> > + * However, some decoder keep a reference on the buffer they passed downstream,
> > + * to re-use it later. In this case, it will not be possible to do zero-copy,
> > + * and we should copy the data back to the buffer and leave it unchanged.
> > + *
> > + * Some other plugins make assumptions that the returned buffer will always have
> > + * at least one memory attached, we cannot just remove it and need to replace the
> > + * memory instead.
> > + */
> > + if ((discard_data = gst_buffer_is_writable(output_buffer)))
> > + gst_buffer_replace_all_memory(output_buffer, gst_allocator_alloc(NULL, 0, NULL));
> > +
> > gst_sample_unref(transform->output_sample);
> > transform->output_sample = NULL;
> > }
> >```
>
> Ah, took me a minute to understand this. To make sure I've got it right:
> this isn't a correctness issue (i.e. the patch would be fine without it,
> if less efficient), but the point is that if we keep our newly allocated
> GstMemory—which no longer has a wg_sample attached—in circulation, the
> buffer pool will continue to use it instead of requesting a new sample,
> which means that samples after the first won't be zero-copied, and to
> avoid this, we fill the GstBuffer with a useless empty GstMemory object.
> Is that right?
Yes. It'd be better to use gst_buffer_remove_all memory, but VA-API
plugins makes some incorrect assumptions and it causes a CRITICAL
message.
> Had to look this up, but apparently the default GstBufferPool will throw
> away buffers if they're modified. I thought the "empty" buffers would
> pile up and never be freed, but evidently not.
>
> I've probably had this question answered before, but can we replace the
> buffer pool itself, instead of just the allocator?
We could reimplement a custom buffer pool that always free buffers, but
that would be more work and still won't solve the underlying problem.
The problem the allocator is solving is that some decoders don't release
their buffers to the pool. The gst_buffer_is_writable check catches that
and gst_buffer_replace_all_memory would fail anyway if we're not the
only ones holding a ref on the buffer. So instead of discarding the data
we copy it back into the buffer unix memory.
Later, when the decoder will eventually release the buffer to the pool,
it will be untainted, and so not freed until the pool is destroyed, and
reusable without going through the allocator. After a few iterations the
pool has enough allocated buffers, we won't get any allocation requests
anymore and our samples are never used directly and we copy the data
normally.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/197#note_1693
June 8, 2022
[PATCH v2 7/7] d3dx10/tests: Add D3DX10GetImageInfoFromMemory thread pump tests.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 122 ++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index fe7a118cec9..7eead7deb4c 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -24,6 +24,32 @@
#define D3DERR_INVALIDCALL 0x8876086c
+#define DEFINE_EXPECT(func) \
+ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+ do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
+
+#define CHECK_EXPECT2(func) \
+ do { \
+ ok(expect_ ##func, "unexpected call " #func "\n"); \
+ called_ ## func = TRUE; \
+ }while(0)
+
+#define CHECK_EXPECT(func) \
+ do { \
+ CHECK_EXPECT2(func); \
+ expect_ ## func = FALSE; \
+ }while(0)
+
+#define CHECK_CALLED(func) \
+ do { \
+ ok(called_ ## func, "expected " #func "\n"); \
+ expect_ ## func = called_ ## func = FALSE; \
+ }while(0)
+
+DEFINE_EXPECT(D3DX10ThreadPump_AddWorkItem);
+
/* 1x1 1bpp bmp image */
static const BYTE test_bmp_1bpp[] =
{
@@ -822,6 +848,94 @@ static unsigned int get_bpp_from_format(DXGI_FORMAT format)
}
}
+static HRESULT WINAPI D3DX10ThreadPump_QueryInterface(ID3DX10ThreadPump *iface, REFIID riid, void **out)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static ULONG WINAPI D3DX10ThreadPump_AddRef(ID3DX10ThreadPump *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI D3DX10ThreadPump_Release(ID3DX10ThreadPump *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI D3DX10ThreadPump_AddWorkItem(ID3DX10ThreadPump *iface, ID3DX10DataLoader *loader,
+ ID3DX10DataProcessor *processor, HRESULT *result, void **object)
+{
+ SIZE_T size;
+ void *data;
+ HRESULT hr;
+
+ CHECK_EXPECT(D3DX10ThreadPump_AddWorkItem);
+ ok(!object, "object = %p\n", object);
+
+ hr = ID3DX10DataLoader_Load(loader);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10DataLoader_Decompress(loader, &data, &size);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10DataProcessor_Process(processor, data, size);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10DataProcessor_CreateDeviceObject(processor, object);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10DataProcessor_Destroy(processor);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10DataLoader_Destroy(loader);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ if (result) *result = S_OK;
+ return S_OK;
+}
+
+static UINT WINAPI D3DX10ThreadPump_GetWorkItemCount(ID3DX10ThreadPump *iface)
+{
+ ok(0, "unexpected call\n");
+ return 0;
+}
+
+static HRESULT WINAPI D3DX10ThreadPump_WaitForAllItems(ID3DX10ThreadPump *iface)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI D3DX10ThreadPump_ProcessDeviceWorkItems(ID3DX10ThreadPump *iface, UINT count)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI D3DX10ThreadPump_PurgeAllItems(ID3DX10ThreadPump *iface)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI D3DX10ThreadPump_GetQueueStatus(ID3DX10ThreadPump *iface, UINT *queue,
+ UINT *processqueue, UINT *devicequeue)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static ID3DX10ThreadPumpVtbl D3DX10ThreadPumpVtbl =
+{
+ D3DX10ThreadPump_QueryInterface,
+ D3DX10ThreadPump_AddRef,
+ D3DX10ThreadPump_Release,
+ D3DX10ThreadPump_AddWorkItem,
+ D3DX10ThreadPump_GetWorkItemCount,
+ D3DX10ThreadPump_WaitForAllItems,
+ D3DX10ThreadPump_ProcessDeviceWorkItems,
+ D3DX10ThreadPump_PurgeAllItems,
+ D3DX10ThreadPump_GetQueueStatus
+};
+static ID3DX10ThreadPump thread_pump = { &D3DX10ThreadPumpVtbl };
+
static ULONG get_refcount(void *iface)
{
IUnknown *unknown = iface;
@@ -1954,6 +2068,14 @@ static void test_get_image_info(void)
winetest_pop_context();
}
+ hr2 = 0xdeadbeef;
+ SET_EXPECT(D3DX10ThreadPump_AddWorkItem);
+ hr = D3DX10GetImageInfoFromMemory(test_image[0].data, test_image[0].size, &thread_pump, &image_info, &hr2);
+ CHECK_CALLED(D3DX10ThreadPump_AddWorkItem);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2);
+ check_image_info(&image_info, test_image, __LINE__);
+
hr2 = 0xdeadbeef;
hr = D3DX10GetImageInfoFromFileW(NULL, NULL, &image_info, &hr2);
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/205
June 8, 2022
[PATCH v2 6/7] d3dx10: Support ID3DX10ThreadPump parameter in D3DX10GetImageInfoFromMemory.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/texture.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index 52d1331d30e..9c7762bc617 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -544,8 +544,26 @@ HRESULT WINAPI D3DX10GetImageInfoFromMemory(const void *src_data, SIZE_T src_dat
if (!src_data)
return E_FAIL;
+
if (pump)
- FIXME("Thread pump is not supported yet.\n");
+ {
+ ID3DX10DataProcessor *processor;
+ ID3DX10DataLoader *loader;
+
+ if (FAILED((hr = D3DX10CreateAsyncMemoryLoader(src_data, src_data_size, &loader))))
+ return hr;
+ if (FAILED((hr = D3DX10CreateAsyncTextureInfoProcessor(img_info, &processor))))
+ {
+ ID3DX10DataLoader_Destroy(loader);
+ return hr;
+ }
+ if (FAILED((hr = ID3DX10ThreadPump_AddWorkItem(pump, loader, processor, result, NULL))))
+ {
+ ID3DX10DataLoader_Destroy(loader);
+ ID3DX10DataProcessor_Destroy(processor);
+ }
+ return hr;
+ }
hr = get_image_info(src_data, src_data_size, img_info);
if (result)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/205
June 8, 2022
[PATCH v2 5/7] d3dx10: Add support for ID3DX10ThreadPump parameter in D3DX10GetImageInfoFromResourceW.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/texture.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index 090d480accd..52d1331d30e 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -411,10 +411,32 @@ HRESULT WINAPI D3DX10GetImageInfoFromResourceW(HMODULE module, const WCHAR *reso
TRACE("module %p, resource %s, pump %p, info %p, result %p.\n",
module, debugstr_w(resource), pump, info, result);
- if (FAILED((hr = load_resourceW(module, resource, &buffer, &size))))
+ if (pump)
+ {
+ ID3DX10DataProcessor *processor;
+ ID3DX10DataLoader *loader;
+
+ if (FAILED((hr = D3DX10CreateAsyncResourceLoaderW(module, resource, &loader))))
+ return hr;
+ if (FAILED((hr = D3DX10CreateAsyncTextureInfoProcessor(info, &processor))))
+ {
+ ID3DX10DataLoader_Destroy(loader);
+ return hr;
+ }
+ if (FAILED((hr = ID3DX10ThreadPump_AddWorkItem(pump, loader, processor, result, NULL))))
+ {
+ ID3DX10DataLoader_Destroy(loader);
+ ID3DX10DataProcessor_Destroy(processor);
+ }
return hr;
+ }
- return D3DX10GetImageInfoFromMemory(buffer, size, pump, info, result);
+ if (FAILED((hr = load_resourceW(module, resource, &buffer, &size))))
+ return hr;
+ hr = get_image_info(buffer, size, info);
+ if (result)
+ *result = hr;
+ return hr;
}
HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_info)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/205
June 8, 2022