Commit 16347299 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

winegstreamer: Implement MFT_MESSAGE_COMMAND_DRAIN for the H264 decoder.

parent db2640d0
...@@ -3879,10 +3879,10 @@ static void test_h264_decoder(void) ...@@ -3879,10 +3879,10 @@ static void test_h264_decoder(void)
hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0);
ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr);
hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0);
ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr);
} }
todo_wine
ok(i == 2, "got %lu iterations\n", i); ok(i == 2, "got %lu iterations\n", i);
todo_wine
ok(h264_encoded_data_len == 2425, "got h264_encoded_data_len %lu\n", h264_encoded_data_len); ok(h264_encoded_data_len == 2425, "got h264_encoded_data_len %lu\n", h264_encoded_data_len);
ok(hr == MF_E_TRANSFORM_STREAM_CHANGE, "ProcessOutput returned %#lx\n", hr); ok(hr == MF_E_TRANSFORM_STREAM_CHANGE, "ProcessOutput returned %#lx\n", hr);
ok(output_status == MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE, "got output[0].dwStatus %#lx\n", output_status); ok(output_status == MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE, "got output[0].dwStatus %#lx\n", output_status);
...@@ -3981,6 +3981,7 @@ static void test_h264_decoder(void) ...@@ -3981,6 +3981,7 @@ static void test_h264_decoder(void)
ok(ref == 1, "Release returned %ld\n", ref); ok(ref == 1, "Release returned %ld\n", ref);
ret = check_mf_sample_collection(output_samples, &expect_output_sample_i420, L"i420frame.bmp"); ret = check_mf_sample_collection(output_samples, &expect_output_sample_i420, L"i420frame.bmp");
todo_wine /* wg_transform_set_output_format() should convert already processed samples instead of dropping */
ok(ret == 0, "got %lu%% diff\n", ret); ok(ret == 0, "got %lu%% diff\n", ret);
IMFCollection_Release(output_samples); IMFCollection_Release(output_samples);
......
...@@ -106,6 +106,7 @@ struct wg_transform *wg_transform_create(const struct wg_format *input_format, ...@@ -106,6 +106,7 @@ struct wg_transform *wg_transform_create(const struct wg_format *input_format,
void wg_transform_destroy(struct wg_transform *transform); void wg_transform_destroy(struct wg_transform *transform);
bool wg_transform_set_output_format(struct wg_transform *transform, struct wg_format *format); bool wg_transform_set_output_format(struct wg_transform *transform, struct wg_format *format);
bool wg_transform_get_status(struct wg_transform *transform, bool *accepts_input); bool wg_transform_get_status(struct wg_transform *transform, bool *accepts_input);
HRESULT wg_transform_drain(struct wg_transform *transform);
unsigned int wg_format_get_max_size(const struct wg_format *format); unsigned int wg_format_get_max_size(const struct wg_format *format);
......
...@@ -614,8 +614,9 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_ ...@@ -614,8 +614,9 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_
TRACE("iface %p, message %#x, param %Ix.\n", iface, message, param); TRACE("iface %p, message %#x, param %Ix.\n", iface, message, param);
if (message == MFT_MESSAGE_SET_D3D_MANAGER) switch (message)
{ {
case MFT_MESSAGE_SET_D3D_MANAGER:
if (FAILED(hr = IMFVideoSampleAllocatorEx_SetDirectXManager(decoder->allocator, (IUnknown *)param))) if (FAILED(hr = IMFVideoSampleAllocatorEx_SetDirectXManager(decoder->allocator, (IUnknown *)param)))
return hr; return hr;
...@@ -625,10 +626,14 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_ ...@@ -625,10 +626,14 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_
else else
decoder->output_info.dwFlags &= ~MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; decoder->output_info.dwFlags &= ~MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
return S_OK; return S_OK;
}
FIXME("Ignoring message %#x.\n", message); case MFT_MESSAGE_COMMAND_DRAIN:
return S_OK; return wg_transform_drain(decoder->wg_transform);
default:
FIXME("Ignoring message %#x.\n", message);
return S_OK;
}
} }
static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
......
...@@ -426,6 +426,21 @@ bool wg_transform_set_output_format(struct wg_transform *transform, struct wg_fo ...@@ -426,6 +426,21 @@ bool wg_transform_set_output_format(struct wg_transform *transform, struct wg_fo
return !WINE_UNIX_CALL(unix_wg_transform_set_output_format, &params); return !WINE_UNIX_CALL(unix_wg_transform_set_output_format, &params);
} }
HRESULT wg_transform_drain(struct wg_transform *transform)
{
NTSTATUS status;
TRACE("transform %p.\n", transform);
if ((status = WINE_UNIX_CALL(unix_wg_transform_drain, transform)))
{
WARN("wg_transform_drain returned status %#lx\n", status);
return HRESULT_FROM_NT(status);
}
return S_OK;
}
#define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1)) #define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
unsigned int wg_format_get_stride(const struct wg_format *format) unsigned int wg_format_get_stride(const struct wg_format *format)
......
...@@ -53,6 +53,7 @@ extern NTSTATUS wg_transform_set_output_format(void *args) DECLSPEC_HIDDEN; ...@@ -53,6 +53,7 @@ extern NTSTATUS wg_transform_set_output_format(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_transform_get_status(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_get_status(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_transform_drain(void *args) DECLSPEC_HIDDEN;
/* wg_allocator.c */ /* wg_allocator.c */
......
...@@ -376,6 +376,7 @@ enum unix_funcs ...@@ -376,6 +376,7 @@ enum unix_funcs
unix_wg_transform_push_data, unix_wg_transform_push_data,
unix_wg_transform_read_data, unix_wg_transform_read_data,
unix_wg_transform_get_status, unix_wg_transform_get_status,
unix_wg_transform_drain,
}; };
#endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ #endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */
...@@ -1939,4 +1939,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] = ...@@ -1939,4 +1939,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_transform_push_data), X(wg_transform_push_data),
X(wg_transform_read_data), X(wg_transform_read_data),
X(wg_transform_get_status), X(wg_transform_get_status),
X(wg_transform_drain),
}; };
...@@ -869,3 +869,38 @@ NTSTATUS wg_transform_get_status(void *args) ...@@ -869,3 +869,38 @@ NTSTATUS wg_transform_get_status(void *args)
params->accepts_input = gst_atomic_queue_length(transform->input_queue) < transform->input_max_length; params->accepts_input = gst_atomic_queue_length(transform->input_queue) < transform->input_max_length;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS wg_transform_drain(void *args)
{
struct wg_transform *transform = args;
GstBuffer *input_buffer;
GstFlowReturn ret;
GstEvent *event;
GST_LOG("transform %p", transform);
while ((input_buffer = gst_atomic_queue_pop(transform->input_queue)))
{
if ((ret = gst_pad_push(transform->my_src, input_buffer)))
GST_WARNING("Failed to push transform input, error %d", ret);
}
if (!(event = gst_event_new_segment_done(GST_FORMAT_TIME, -1))
|| !gst_pad_push_event(transform->my_src, event))
goto error;
if (!(event = gst_event_new_eos())
|| !gst_pad_push_event(transform->my_src, event))
goto error;
if (!(event = gst_event_new_stream_start("stream"))
|| !gst_pad_push_event(transform->my_src, event))
goto error;
if (!(event = gst_event_new_segment(&transform->segment))
|| !gst_pad_push_event(transform->my_src, event))
goto error;
return STATUS_SUCCESS;
error:
GST_ERROR("Failed to drain transform %p.", transform);
return STATUS_UNSUCCESSFUL;
}
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