Commit e36547d2 authored by Ziqing Hui's avatar Ziqing Hui Committed by Alexandre Julliard

winestreamer: Implement {Begin,End}Finalize for media sink.

parent 7e575d68
...@@ -116,6 +116,7 @@ HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_ ...@@ -116,6 +116,7 @@ HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_
HRESULT wg_muxer_start(wg_muxer_t muxer); HRESULT wg_muxer_start(wg_muxer_t muxer);
HRESULT wg_muxer_push_sample(wg_muxer_t muxer, struct wg_sample *sample, UINT32 stream_id); HRESULT wg_muxer_push_sample(wg_muxer_t muxer, struct wg_sample *sample, UINT32 stream_id);
HRESULT wg_muxer_read_data(wg_muxer_t muxer, void *buffer, UINT32 *size, UINT64 *offset); HRESULT wg_muxer_read_data(wg_muxer_t muxer, void *buffer, UINT32 *size, UINT64 *offset);
HRESULT wg_muxer_finalize(wg_muxer_t muxer);
unsigned int wg_format_get_bytes_for_uncompressed(wg_video_format format, unsigned int width, unsigned int height); unsigned int wg_format_get_bytes_for_uncompressed(wg_video_format format, unsigned int width, unsigned int height);
unsigned int wg_format_get_max_size(const struct wg_format *format); unsigned int wg_format_get_max_size(const struct wg_format *format);
......
...@@ -567,6 +567,21 @@ HRESULT wg_muxer_read_data(wg_muxer_t muxer, void *buffer, UINT32 *size, UINT64 ...@@ -567,6 +567,21 @@ HRESULT wg_muxer_read_data(wg_muxer_t muxer, void *buffer, UINT32 *size, UINT64
return HRESULT_FROM_NT(status); return HRESULT_FROM_NT(status);
} }
HRESULT wg_muxer_finalize(wg_muxer_t muxer)
{
NTSTATUS status;
TRACE("muxer %#I64x.\n", muxer);
if ((status = WINE_UNIX_CALL(unix_wg_muxer_finalize, &muxer)))
{
WARN("Failed to finalize, 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)
......
...@@ -32,6 +32,7 @@ enum async_op ...@@ -32,6 +32,7 @@ enum async_op
ASYNC_STOP, ASYNC_STOP,
ASYNC_PAUSE, ASYNC_PAUSE,
ASYNC_PROCESS, ASYNC_PROCESS,
ASYNC_FINALIZE,
}; };
struct async_command struct async_command
...@@ -48,6 +49,10 @@ struct async_command ...@@ -48,6 +49,10 @@ struct async_command
IMFSample *sample; IMFSample *sample;
UINT32 stream_id; UINT32 stream_id;
} process; } process;
struct
{
IMFAsyncResult *result;
} finalize;
} u; } u;
}; };
...@@ -80,6 +85,7 @@ struct media_sink ...@@ -80,6 +85,7 @@ struct media_sink
STATE_STARTED, STATE_STARTED,
STATE_STOPPED, STATE_STOPPED,
STATE_PAUSED, STATE_PAUSED,
STATE_FINALIZED,
STATE_SHUTDOWN, STATE_SHUTDOWN,
} state; } state;
...@@ -155,6 +161,8 @@ static ULONG WINAPI async_command_Release(IUnknown *iface) ...@@ -155,6 +161,8 @@ static ULONG WINAPI async_command_Release(IUnknown *iface)
{ {
if (command->op == ASYNC_PROCESS && command->u.process.sample) if (command->op == ASYNC_PROCESS && command->u.process.sample)
IMFSample_Release(command->u.process.sample); IMFSample_Release(command->u.process.sample);
else if (command->op == ASYNC_FINALIZE && command->u.finalize.result)
IMFAsyncResult_Release(command->u.finalize.result);
free(command); free(command);
} }
...@@ -631,6 +639,51 @@ static HRESULT media_sink_process(struct media_sink *media_sink, IMFSample *samp ...@@ -631,6 +639,51 @@ static HRESULT media_sink_process(struct media_sink *media_sink, IMFSample *samp
return hr; return hr;
} }
static HRESULT media_sink_begin_finalize(struct media_sink *media_sink, IMFAsyncCallback *callback, IUnknown *state)
{
struct async_command *command;
IMFAsyncResult *result;
HRESULT hr;
if (media_sink->state == STATE_SHUTDOWN)
return MF_E_SHUTDOWN;
if (!callback)
return S_OK;
if (FAILED(hr = async_command_create(ASYNC_FINALIZE, &command)))
return hr;
if (FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &result)))
{
IUnknown_Release(&command->IUnknown_iface);
return hr;
}
IMFAsyncResult_AddRef((command->u.finalize.result = result));
hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD,
&media_sink->async_callback, &command->IUnknown_iface);
IUnknown_Release(&command->IUnknown_iface);
return hr;
}
static HRESULT media_sink_finalize(struct media_sink *media_sink, IMFAsyncResult *result)
{
HRESULT hr;
media_sink->state = STATE_FINALIZED;
hr = wg_muxer_finalize(media_sink->muxer);
if (SUCCEEDED(hr))
hr = media_sink_write_stream(media_sink);
IMFAsyncResult_SetStatus(result, hr);
MFInvokeCallback(result);
return hr;
}
static HRESULT WINAPI media_sink_QueryInterface(IMFFinalizableMediaSink *iface, REFIID riid, void **obj) static HRESULT WINAPI media_sink_QueryInterface(IMFFinalizableMediaSink *iface, REFIID riid, void **obj)
{ {
struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface); struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface);
...@@ -870,16 +923,23 @@ static HRESULT WINAPI media_sink_Shutdown(IMFFinalizableMediaSink *iface) ...@@ -870,16 +923,23 @@ static HRESULT WINAPI media_sink_Shutdown(IMFFinalizableMediaSink *iface)
static HRESULT WINAPI media_sink_BeginFinalize(IMFFinalizableMediaSink *iface, IMFAsyncCallback *callback, IUnknown *state) static HRESULT WINAPI media_sink_BeginFinalize(IMFFinalizableMediaSink *iface, IMFAsyncCallback *callback, IUnknown *state)
{ {
FIXME("iface %p, callback %p, state %p stub!\n", iface, callback, state); struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface);
HRESULT hr;
return E_NOTIMPL; TRACE("iface %p, callback %p, state %p.\n", iface, callback, state);
EnterCriticalSection(&media_sink->cs);
hr = media_sink_begin_finalize(media_sink, callback, state);
LeaveCriticalSection(&media_sink->cs);
return hr;
} }
static HRESULT WINAPI media_sink_EndFinalize(IMFFinalizableMediaSink *iface, IMFAsyncResult *result) static HRESULT WINAPI media_sink_EndFinalize(IMFFinalizableMediaSink *iface, IMFAsyncResult *result)
{ {
FIXME("iface %p, result %p stub!\n", iface, result); TRACE("iface %p, result %p.\n", iface, result);
return E_NOTIMPL; return result ? IMFAsyncResult_GetStatus(result) : E_INVALIDARG;
} }
static const IMFFinalizableMediaSinkVtbl media_sink_vtbl = static const IMFFinalizableMediaSinkVtbl media_sink_vtbl =
...@@ -1136,6 +1196,10 @@ static HRESULT WINAPI media_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsy ...@@ -1136,6 +1196,10 @@ static HRESULT WINAPI media_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsy
if (FAILED(hr = media_sink_process(media_sink, command->u.process.sample, command->u.process.stream_id))) if (FAILED(hr = media_sink_process(media_sink, command->u.process.sample, command->u.process.stream_id)))
WARN("Failed to process sample, hr %#lx.\n", hr); WARN("Failed to process sample, hr %#lx.\n", hr);
break; break;
case ASYNC_FINALIZE:
if (FAILED(hr = media_sink_finalize(media_sink, command->u.finalize.result)))
WARN("Failed to finalize, hr %#lx.\n", hr);
break;
default: default:
WARN("Unsupported op %u.\n", command->op); WARN("Unsupported op %u.\n", command->op);
break; break;
......
...@@ -71,6 +71,7 @@ extern NTSTATUS wg_muxer_add_stream(void *args) DECLSPEC_HIDDEN; ...@@ -71,6 +71,7 @@ extern NTSTATUS wg_muxer_add_stream(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_start(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_muxer_start(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_push_sample(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_muxer_push_sample(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_read_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_muxer_read_data(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_finalize(void *args) DECLSPEC_HIDDEN;
/* wg_allocator.c */ /* wg_allocator.c */
......
...@@ -446,6 +446,7 @@ enum unix_funcs ...@@ -446,6 +446,7 @@ enum unix_funcs
unix_wg_muxer_start, unix_wg_muxer_start,
unix_wg_muxer_push_sample, unix_wg_muxer_push_sample,
unix_wg_muxer_read_data, unix_wg_muxer_read_data,
unix_wg_muxer_finalize,
unix_wg_funcs_count, unix_wg_funcs_count,
}; };
......
...@@ -523,3 +523,9 @@ NTSTATUS wg_muxer_read_data(void *args) ...@@ -523,3 +523,9 @@ NTSTATUS wg_muxer_read_data(void *args)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS wg_muxer_finalize(void *args)
{
GST_FIXME("Not implemented.");
return STATUS_NOT_IMPLEMENTED;
}
...@@ -1922,6 +1922,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = ...@@ -1922,6 +1922,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_muxer_start), X(wg_muxer_start),
X(wg_muxer_push_sample), X(wg_muxer_push_sample),
X(wg_muxer_read_data), X(wg_muxer_read_data),
X(wg_muxer_finalize),
}; };
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count); C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count);
...@@ -2253,6 +2254,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = ...@@ -2253,6 +2254,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
X(wg_muxer_start), X(wg_muxer_start),
X64(wg_muxer_push_sample), X64(wg_muxer_push_sample),
X64(wg_muxer_read_data), X64(wg_muxer_read_data),
X(wg_muxer_finalize),
}; };
C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_wg_funcs_count); C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_wg_funcs_count);
......
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