winegstreamer: Introduce new wg_sample_create_quartz helper for quartz_transform.c.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
This commit is contained in:
Rémi Bernon 2022-06-13 11:30:52 +02:00 committed by Alexandre Julliard
parent b2828c1c88
commit 2bbdd1eee6
3 changed files with 75 additions and 20 deletions

View file

@ -127,6 +127,7 @@ 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 wg_sample_create_mf(IMFSample *sample, struct wg_sample **out);
HRESULT wg_sample_create_quartz(IMediaSample *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,

View file

@ -290,7 +290,7 @@ static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID i
static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSample *sample)
{
struct transform *filter = impl_from_strmbase_filter(pin->pin.filter);
struct wg_sample input_wg_sample = {0};
struct wg_sample *wg_sample;
REFERENCE_TIME start_time;
REFERENCE_TIME end_time;
HRESULT hr;
@ -311,50 +311,47 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa
if (filter->sink.flushing)
return S_FALSE;
input_wg_sample.max_size = IMediaSample_GetSize(sample);
input_wg_sample.size = IMediaSample_GetActualDataLength(sample);
hr = IMediaSample_GetPointer(sample, &input_wg_sample.data);
hr = wg_sample_create_quartz(sample, &wg_sample);
if (FAILED(hr))
return hr;
hr = IMediaSample_GetTime(sample, &start_time, &end_time);
if (SUCCEEDED(hr))
{
input_wg_sample.pts = start_time;
input_wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS;
wg_sample->pts = start_time;
wg_sample->flags |= WG_SAMPLE_FLAG_HAS_PTS;
}
if (hr == S_OK)
{
input_wg_sample.duration = end_time - start_time;
input_wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION;
wg_sample->duration = end_time - start_time;
wg_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION;
}
hr = wg_transform_push_data(filter->transform, &input_wg_sample);
hr = wg_transform_push_data(filter->transform, wg_sample);
wg_sample_release(wg_sample);
if (FAILED(hr))
return hr;
for (;;)
{
struct wg_sample output_wg_sample = {0};
IMediaSample *output_sample;
hr = IMemAllocator_GetBuffer(filter->source.pAllocator, &output_sample, NULL, NULL, 0);
if (FAILED(hr))
return hr;
output_wg_sample.max_size = IMediaSample_GetSize(output_sample);
hr = IMediaSample_GetPointer(output_sample, &output_wg_sample.data);
hr = wg_sample_create_quartz(output_sample, &wg_sample);
if (FAILED(hr))
{
IMediaSample_Release(output_sample);
return hr;
}
hr = wg_transform_read_data(filter->transform, &output_wg_sample, NULL);
hr = wg_transform_read_data(filter->transform, wg_sample, NULL);
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
{
wg_sample_release(wg_sample);
IMediaSample_Release(output_sample);
break;
}
@ -362,23 +359,25 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa
{
if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
FIXME("Unexpected stream format change!\n");
wg_sample_release(wg_sample);
IMediaSample_Release(output_sample);
return hr;
}
hr = IMediaSample_SetActualDataLength(output_sample, output_wg_sample.size);
hr = IMediaSample_SetActualDataLength(output_sample, wg_sample->size);
if (FAILED(hr))
{
wg_sample_release(wg_sample);
IMediaSample_Release(output_sample);
return hr;
}
if (output_wg_sample.flags & WG_SAMPLE_FLAG_HAS_PTS)
if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS)
{
start_time = output_wg_sample.pts;
if (output_wg_sample.flags & WG_SAMPLE_FLAG_HAS_DURATION)
start_time = wg_sample->pts;
if (wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION)
{
end_time = start_time + output_wg_sample.duration;
end_time = start_time + wg_sample->duration;
IMediaSample_SetTime(output_sample, &start_time, &end_time);
}
else
@ -386,6 +385,7 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa
IMediaSample_SetTime(output_sample, &start_time, NULL);
}
}
wg_sample_release(wg_sample);
hr = IMemInputPin_Receive(filter->source.pMemInputPin, output_sample);
if (FAILED(hr))

View file

@ -25,6 +25,7 @@
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
WINE_DECLARE_DEBUG_CHANNEL(quartz);
struct wg_sample_queue
{
@ -51,6 +52,10 @@ struct sample
IMFSample *sample;
IMFMediaBuffer *buffer;
} mf;
struct
{
IMediaSample *sample;
} quartz;
} u;
};
@ -110,6 +115,55 @@ fail:
return hr;
}
static const struct wg_sample_ops quartz_sample_ops;
static inline struct sample *unsafe_quartz_from_wg_sample(struct wg_sample *wg_sample)
{
struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);
if (sample->ops != &quartz_sample_ops) return NULL;
return sample;
}
static void quartz_sample_destroy(struct wg_sample *wg_sample)
{
struct sample *sample = unsafe_quartz_from_wg_sample(wg_sample);
TRACE_(quartz)("wg_sample %p.\n", wg_sample);
IMediaSample_Release(sample->u.quartz.sample);
}
static const struct wg_sample_ops quartz_sample_ops =
{
quartz_sample_destroy,
};
HRESULT wg_sample_create_quartz(IMediaSample *media_sample, struct wg_sample **out)
{
DWORD current_length, max_length;
struct sample *sample;
BYTE *buffer;
HRESULT hr;
if (FAILED(hr = IMediaSample_GetPointer(media_sample, &buffer)))
return hr;
current_length = IMediaSample_GetActualDataLength(media_sample);
max_length = IMediaSample_GetSize(media_sample);
if (!(sample = calloc(1, sizeof(*sample))))
return E_OUTOFMEMORY;
IMediaSample_AddRef((sample->u.quartz.sample = media_sample));
sample->wg_sample.data = buffer;
sample->wg_sample.size = current_length;
sample->wg_sample.max_size = max_length;
sample->ops = &quartz_sample_ops;
TRACE_(quartz)("Created wg_sample %p for IMediaSample %p.\n", &sample->wg_sample, media_sample);
*out = &sample->wg_sample;
return S_OK;
}
void wg_sample_release(struct wg_sample *wg_sample)
{
struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample);