mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:08:30 +00:00
winegstreamer: Request the new transform output format explicitly.
This commit is contained in:
parent
3dd3535a2c
commit
1e8e0d41b4
|
@ -521,7 +521,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
return hr;
|
||||
|
||||
if (SUCCEEDED(hr = wg_transform_read_mf(decoder->wg_transform, samples->pSample,
|
||||
info.cbSize, NULL, &samples->dwStatus)))
|
||||
info.cbSize, &samples->dwStatus)))
|
||||
wg_sample_queue_flush(decoder->wg_sample_queue, false);
|
||||
else
|
||||
samples->dwStatus = MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE;
|
||||
|
|
|
@ -582,7 +582,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
return hr;
|
||||
|
||||
if (SUCCEEDED(hr = wg_transform_read_mf(impl->wg_transform, samples->pSample,
|
||||
info.cbSize, NULL, &samples->dwStatus)))
|
||||
info.cbSize, &samples->dwStatus)))
|
||||
wg_sample_queue_flush(impl->wg_sample_queue, false);
|
||||
|
||||
return hr;
|
||||
|
|
|
@ -88,6 +88,7 @@ HRESULT wg_transform_create_mf(IMFMediaType *input_type, IMFMediaType *output_ty
|
|||
HRESULT wg_transform_create_quartz(const AM_MEDIA_TYPE *input_format, const AM_MEDIA_TYPE *output_format,
|
||||
const struct wg_transform_attrs *attrs, wg_transform_t *transform);
|
||||
void wg_transform_destroy(wg_transform_t transform);
|
||||
bool wg_transform_get_output_format(wg_transform_t transform, struct wg_format *format);
|
||||
bool wg_transform_set_output_format(wg_transform_t transform, struct wg_format *format);
|
||||
bool wg_transform_get_status(wg_transform_t transform, bool *accepts_input);
|
||||
HRESULT wg_transform_drain(wg_transform_t transform);
|
||||
|
@ -146,10 +147,16 @@ HRESULT wg_transform_push_quartz(wg_transform_t transform, struct wg_sample *sam
|
|||
HRESULT wg_transform_push_dmo(wg_transform_t transform, IMediaBuffer *media_buffer,
|
||||
DWORD flags, REFERENCE_TIME time_stamp, REFERENCE_TIME time_length, struct wg_sample_queue *queue);
|
||||
HRESULT wg_transform_read_mf(wg_transform_t transform, IMFSample *sample,
|
||||
DWORD sample_size, struct wg_format *format, DWORD *flags);
|
||||
DWORD sample_size, DWORD *flags);
|
||||
HRESULT wg_transform_read_quartz(wg_transform_t transform, struct wg_sample *sample);
|
||||
HRESULT wg_transform_read_dmo(wg_transform_t transform, DMO_OUTPUT_DATA_BUFFER *buffer);
|
||||
|
||||
/* These unixlib entry points should not be used directly, they assume samples
|
||||
* to be queued and zero-copy support, use the helpers below instead.
|
||||
*/
|
||||
HRESULT wg_transform_push_data(wg_transform_t transform, struct wg_sample *sample);
|
||||
HRESULT wg_transform_read_data(wg_transform_t transform, struct wg_sample *sample);
|
||||
|
||||
HRESULT gstreamer_byte_stream_handler_create(REFIID riid, void **obj);
|
||||
|
||||
unsigned int wg_format_get_stride(const struct wg_format *format);
|
||||
|
|
|
@ -415,18 +415,16 @@ HRESULT wg_transform_push_data(wg_transform_t transform, struct wg_sample *sampl
|
|||
return params.result;
|
||||
}
|
||||
|
||||
HRESULT wg_transform_read_data(wg_transform_t transform, struct wg_sample *sample,
|
||||
struct wg_format *format)
|
||||
HRESULT wg_transform_read_data(wg_transform_t transform, struct wg_sample *sample)
|
||||
{
|
||||
struct wg_transform_read_data_params params =
|
||||
{
|
||||
.transform = transform,
|
||||
.sample = sample,
|
||||
.format = format,
|
||||
};
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("transform %#I64x, sample %p, format %p.\n", transform, sample, format);
|
||||
TRACE("transform %#I64x, sample %p.\n", transform, sample);
|
||||
|
||||
if ((status = WINE_UNIX_CALL(unix_wg_transform_read_data, ¶ms)))
|
||||
return HRESULT_FROM_NT(status);
|
||||
|
@ -450,6 +448,19 @@ bool wg_transform_get_status(wg_transform_t transform, bool *accepts_input)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool wg_transform_get_output_format(wg_transform_t transform, struct wg_format *format)
|
||||
{
|
||||
struct wg_transform_get_output_format_params params =
|
||||
{
|
||||
.transform = transform,
|
||||
.format = format,
|
||||
};
|
||||
|
||||
TRACE("transform %#I64x, format %p.\n", transform, format);
|
||||
|
||||
return !WINE_UNIX_CALL(unix_wg_transform_get_output_format, ¶ms);
|
||||
}
|
||||
|
||||
bool wg_transform_set_output_format(wg_transform_t transform, struct wg_format *format)
|
||||
{
|
||||
struct wg_transform_set_output_format_params params =
|
||||
|
|
|
@ -541,7 +541,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
return hr;
|
||||
|
||||
if (SUCCEEDED(hr = wg_transform_read_mf(impl->wg_transform, samples->pSample,
|
||||
info.cbSize, NULL, &samples->dwStatus)))
|
||||
info.cbSize, &samples->dwStatus)))
|
||||
wg_sample_queue_flush(impl->wg_sample_queue, false);
|
||||
|
||||
return hr;
|
||||
|
|
|
@ -56,6 +56,7 @@ extern GstCaps *wg_format_to_caps(const struct wg_format *format);
|
|||
|
||||
extern NTSTATUS wg_transform_create(void *args);
|
||||
extern NTSTATUS wg_transform_destroy(void *args);
|
||||
extern NTSTATUS wg_transform_get_output_format(void *args);
|
||||
extern NTSTATUS wg_transform_set_output_format(void *args);
|
||||
extern NTSTATUS wg_transform_push_data(void *args);
|
||||
extern NTSTATUS wg_transform_read_data(void *args);
|
||||
|
|
|
@ -325,10 +325,15 @@ struct wg_transform_read_data_params
|
|||
{
|
||||
wg_transform_t transform;
|
||||
struct wg_sample *sample;
|
||||
struct wg_format *format;
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
struct wg_transform_get_output_format_params
|
||||
{
|
||||
wg_transform_t transform;
|
||||
struct wg_format *format;
|
||||
};
|
||||
|
||||
struct wg_transform_set_output_format_params
|
||||
{
|
||||
wg_transform_t transform;
|
||||
|
@ -410,6 +415,7 @@ enum unix_funcs
|
|||
|
||||
unix_wg_transform_create,
|
||||
unix_wg_transform_destroy,
|
||||
unix_wg_transform_get_output_format,
|
||||
unix_wg_transform_set_output_format,
|
||||
|
||||
unix_wg_transform_push_data,
|
||||
|
|
|
@ -852,14 +852,17 @@ static HRESULT output_sample(struct video_decoder *decoder, IMFSample **out, IMF
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT handle_stream_type_change(struct video_decoder *decoder, const struct wg_format *format)
|
||||
static HRESULT handle_stream_type_change(struct video_decoder *decoder)
|
||||
{
|
||||
UINT64 frame_size, frame_rate;
|
||||
struct wg_format format;
|
||||
HRESULT hr;
|
||||
|
||||
if (decoder->stream_type)
|
||||
IMFMediaType_Release(decoder->stream_type);
|
||||
if (!(decoder->stream_type = mf_media_type_from_wg_format(format)))
|
||||
if (!(wg_transform_get_output_format(decoder->wg_transform, &format)))
|
||||
return E_FAIL;
|
||||
if (!(decoder->stream_type = mf_media_type_from_wg_format(&format)))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_RATE, &frame_rate))
|
||||
|
@ -879,7 +882,6 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
|
||||
{
|
||||
struct video_decoder *decoder = impl_from_IMFTransform(iface);
|
||||
struct wg_format wg_format;
|
||||
UINT32 sample_size;
|
||||
LONGLONG duration;
|
||||
IMFSample *sample;
|
||||
|
@ -929,7 +931,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
}
|
||||
|
||||
if (SUCCEEDED(hr = wg_transform_read_mf(decoder->wg_transform, sample,
|
||||
sample_size, &wg_format, &samples->dwStatus)))
|
||||
sample_size, &samples->dwStatus)))
|
||||
{
|
||||
wg_sample_queue_flush(decoder->wg_sample_queue, false);
|
||||
|
||||
|
@ -948,7 +950,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
{
|
||||
samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
|
||||
*status |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
|
||||
hr = handle_stream_type_change(decoder, &wg_format);
|
||||
hr = handle_stream_type_change(decoder);
|
||||
}
|
||||
|
||||
if (decoder->output_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES)
|
||||
|
|
|
@ -693,8 +693,7 @@ static HRESULT WINAPI video_processor_ProcessOutput(IMFTransform *iface, DWORD f
|
|||
IMFSample_AddRef(output_sample);
|
||||
}
|
||||
|
||||
if (FAILED(hr = wg_transform_read_mf(impl->wg_transform, output_sample, info.cbSize,
|
||||
NULL, &samples->dwStatus)))
|
||||
if (FAILED(hr = wg_transform_read_mf(impl->wg_transform, output_sample, info.cbSize, &samples->dwStatus)))
|
||||
goto done;
|
||||
wg_sample_queue_flush(impl->wg_sample_queue, false);
|
||||
|
||||
|
|
|
@ -1889,6 +1889,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
|
|||
|
||||
X(wg_transform_create),
|
||||
X(wg_transform_destroy),
|
||||
X(wg_transform_get_output_format),
|
||||
X(wg_transform_set_output_format),
|
||||
|
||||
X(wg_transform_push_data),
|
||||
|
@ -2074,6 +2075,21 @@ NTSTATUS wow64_wg_transform_create(void *args)
|
|||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS wow64_wg_transform_get_output_format(void *args)
|
||||
{
|
||||
struct
|
||||
{
|
||||
wg_transform_t transform;
|
||||
PTR32 format;
|
||||
} *params32 = args;
|
||||
struct wg_transform_get_output_format_params params =
|
||||
{
|
||||
.transform = params32->transform,
|
||||
.format = ULongToPtr(params32->format),
|
||||
};
|
||||
return wg_transform_get_output_format(¶ms);
|
||||
}
|
||||
|
||||
NTSTATUS wow64_wg_transform_set_output_format(void *args)
|
||||
{
|
||||
struct
|
||||
|
@ -2115,14 +2131,12 @@ NTSTATUS wow64_wg_transform_read_data(void *args)
|
|||
{
|
||||
wg_transform_t transform;
|
||||
PTR32 sample;
|
||||
PTR32 format;
|
||||
HRESULT result;
|
||||
} *params32 = args;
|
||||
struct wg_transform_read_data_params params =
|
||||
{
|
||||
.transform = params32->transform,
|
||||
.sample = ULongToPtr(params32->sample),
|
||||
.format = ULongToPtr(params32->format),
|
||||
};
|
||||
NTSTATUS ret;
|
||||
|
||||
|
@ -2240,6 +2254,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
|
|||
|
||||
X64(wg_transform_create),
|
||||
X(wg_transform_destroy),
|
||||
X64(wg_transform_get_output_format),
|
||||
X64(wg_transform_set_output_format),
|
||||
|
||||
X64(wg_transform_push_data),
|
||||
|
|
|
@ -303,13 +303,6 @@ void wg_sample_queue_destroy(struct wg_sample_queue *queue)
|
|||
free(queue);
|
||||
}
|
||||
|
||||
/* These unixlib entry points should not be used directly, they assume samples
|
||||
* to be queued and zero-copy support, use the helpers below instead.
|
||||
*/
|
||||
HRESULT wg_transform_push_data(wg_transform_t transform, struct wg_sample *sample);
|
||||
HRESULT wg_transform_read_data(wg_transform_t transform, struct wg_sample *sample,
|
||||
struct wg_format *format);
|
||||
|
||||
HRESULT wg_transform_push_mf(wg_transform_t transform, IMFSample *sample,
|
||||
struct wg_sample_queue *queue)
|
||||
{
|
||||
|
@ -346,23 +339,21 @@ HRESULT wg_transform_push_mf(wg_transform_t transform, IMFSample *sample,
|
|||
}
|
||||
|
||||
HRESULT wg_transform_read_mf(wg_transform_t transform, IMFSample *sample,
|
||||
DWORD sample_size, struct wg_format *format, DWORD *flags)
|
||||
DWORD sample_size, DWORD *flags)
|
||||
{
|
||||
struct wg_sample *wg_sample;
|
||||
IMFMediaBuffer *buffer;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE_(mfplat)("transform %#I64x, sample %p, format %p, flags %p.\n", transform, sample, format, flags);
|
||||
TRACE_(mfplat)("transform %#I64x, sample %p, flags %p.\n", transform, sample, flags);
|
||||
|
||||
if (FAILED(hr = wg_sample_create_mf(sample, &wg_sample)))
|
||||
return hr;
|
||||
|
||||
wg_sample->size = 0;
|
||||
|
||||
if (FAILED(hr = wg_transform_read_data(transform, wg_sample, format)))
|
||||
if (FAILED(hr = wg_transform_read_data(transform, wg_sample)))
|
||||
{
|
||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE && !format)
|
||||
FIXME("Unexpected stream format change!\n");
|
||||
wg_sample_release(wg_sample);
|
||||
return hr;
|
||||
}
|
||||
|
@ -430,7 +421,7 @@ HRESULT wg_transform_read_quartz(wg_transform_t transform, struct wg_sample *wg_
|
|||
|
||||
TRACE_(mfplat)("transform %#I64x, wg_sample %p.\n", transform, wg_sample);
|
||||
|
||||
if (FAILED(hr = wg_transform_read_data(transform, wg_sample, NULL)))
|
||||
if (FAILED(hr = wg_transform_read_data(transform, wg_sample)))
|
||||
{
|
||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
|
||||
FIXME("Unexpected stream format change!\n");
|
||||
|
@ -505,7 +496,7 @@ HRESULT wg_transform_read_dmo(wg_transform_t transform, DMO_OUTPUT_DATA_BUFFER *
|
|||
return hr;
|
||||
wg_sample->size = 0;
|
||||
|
||||
if (FAILED(hr = wg_transform_read_data(transform, wg_sample, NULL)))
|
||||
if (FAILED(hr = wg_transform_read_data(transform, wg_sample)))
|
||||
{
|
||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
|
||||
TRACE_(mfplat)("Stream format changed.\n");
|
||||
|
|
|
@ -616,6 +616,48 @@ out:
|
|||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS wg_transform_get_output_format(void *args)
|
||||
{
|
||||
struct wg_transform_get_output_format_params *params = args;
|
||||
struct wg_transform *transform = get_transform(params->transform);
|
||||
struct wg_format *format = params->format;
|
||||
GstVideoInfo video_info;
|
||||
GstCaps *output_caps;
|
||||
|
||||
if (transform->output_sample)
|
||||
output_caps = gst_sample_get_caps(transform->output_sample);
|
||||
else
|
||||
output_caps = transform->output_caps;
|
||||
|
||||
GST_INFO("transform %p output caps %"GST_PTR_FORMAT, transform, output_caps);
|
||||
|
||||
wg_format_from_caps(format, output_caps);
|
||||
|
||||
if (stream_type_from_caps(output_caps) == GST_STREAM_TYPE_VIDEO
|
||||
&& gst_video_info_from_caps(&video_info, output_caps))
|
||||
{
|
||||
gsize plane_align = transform->attrs.output_plane_align;
|
||||
GstVideoAlignment align = {0};
|
||||
|
||||
/* set the desired output buffer alignment on the dest video info */
|
||||
align_video_info_planes(plane_align, &video_info, &align);
|
||||
|
||||
GST_INFO("Returning video alignment left %u, top %u, right %u, bottom %u.", align.padding_left,
|
||||
align.padding_top, align.padding_right, align.padding_bottom);
|
||||
|
||||
format->u.video.padding.left = align.padding_left;
|
||||
format->u.video.width += format->u.video.padding.left;
|
||||
format->u.video.padding.right = align.padding_right;
|
||||
format->u.video.width += format->u.video.padding.right;
|
||||
format->u.video.padding.top = align.padding_top;
|
||||
format->u.video.height += format->u.video.padding.top;
|
||||
format->u.video.padding.bottom = align.padding_bottom;
|
||||
format->u.video.height += format->u.video.padding.bottom;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS wg_transform_set_output_format(void *args)
|
||||
{
|
||||
struct wg_transform_set_output_format_params *params = args;
|
||||
|
@ -927,7 +969,6 @@ NTSTATUS wg_transform_read_data(void *args)
|
|||
struct wg_transform *transform = get_transform(params->transform);
|
||||
GstVideoInfo src_video_info, dst_video_info;
|
||||
struct wg_sample *sample = params->sample;
|
||||
struct wg_format *format = params->format;
|
||||
GstVideoAlignment align = {0};
|
||||
GstBuffer *output_buffer;
|
||||
GstCaps *output_caps;
|
||||
|
@ -961,29 +1002,6 @@ NTSTATUS wg_transform_read_data(void *args)
|
|||
if (GST_MINI_OBJECT_FLAG_IS_SET(transform->output_sample, GST_SAMPLE_FLAG_WG_CAPS_CHANGED))
|
||||
{
|
||||
GST_MINI_OBJECT_FLAG_UNSET(transform->output_sample, GST_SAMPLE_FLAG_WG_CAPS_CHANGED);
|
||||
|
||||
GST_INFO("transform %p output caps %"GST_PTR_FORMAT, transform, output_caps);
|
||||
|
||||
if (format)
|
||||
{
|
||||
wg_format_from_caps(format, output_caps);
|
||||
|
||||
if (format->major_type == WG_MAJOR_TYPE_VIDEO)
|
||||
{
|
||||
GST_INFO("Returning video alignment left %u, top %u, right %u, bottom %u.", align.padding_left,
|
||||
align.padding_top, align.padding_right, align.padding_bottom);
|
||||
|
||||
format->u.video.padding.left = align.padding_left;
|
||||
format->u.video.width += format->u.video.padding.left;
|
||||
format->u.video.padding.right = align.padding_right;
|
||||
format->u.video.width += format->u.video.padding.right;
|
||||
format->u.video.padding.top = align.padding_top;
|
||||
format->u.video.height += format->u.video.padding.top;
|
||||
format->u.video.padding.bottom = align.padding_bottom;
|
||||
format->u.video.height += format->u.video.padding.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
params->result = MF_E_TRANSFORM_STREAM_CHANGE;
|
||||
GST_INFO("Format changed detected, returning no output");
|
||||
wg_allocator_release_sample(transform->allocator, sample, false);
|
||||
|
|
|
@ -557,7 +557,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
return hr;
|
||||
|
||||
if (SUCCEEDED(hr = wg_transform_read_mf(decoder->wg_transform, samples->pSample,
|
||||
info.cbSize, NULL, &samples->dwStatus)))
|
||||
info.cbSize, &samples->dwStatus)))
|
||||
wg_sample_queue_flush(decoder->wg_sample_queue, false);
|
||||
|
||||
return hr;
|
||||
|
|
Loading…
Reference in a new issue