Commit 37b25483 authored by Ziqing Hui's avatar Ziqing Hui Committed by Alexandre Julliard

winegstreamer: Implement ProcessSample for media sink.

parent dfffe7b4
...@@ -114,6 +114,7 @@ HRESULT wg_muxer_create(const char *format, wg_muxer_t *muxer); ...@@ -114,6 +114,7 @@ HRESULT wg_muxer_create(const char *format, wg_muxer_t *muxer);
void wg_muxer_destroy(wg_muxer_t muxer); void wg_muxer_destroy(wg_muxer_t muxer);
HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_format *format); HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_format *format);
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);
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);
......
...@@ -523,6 +523,27 @@ HRESULT wg_muxer_start(wg_muxer_t muxer) ...@@ -523,6 +523,27 @@ HRESULT wg_muxer_start(wg_muxer_t muxer)
return S_OK; return S_OK;
} }
HRESULT wg_muxer_push_sample(wg_muxer_t muxer, struct wg_sample *sample, UINT32 steam_id)
{
struct wg_muxer_push_sample_params params =
{
.muxer = muxer,
.sample = sample,
.stream_id = steam_id,
};
NTSTATUS status;
TRACE("muxer %#I64x, sample %p.\n", muxer, sample);
if ((status = WINE_UNIX_CALL(unix_wg_muxer_push_sample, &params)))
{
WARN("Failed to push sample, 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)
......
...@@ -31,6 +31,7 @@ enum async_op ...@@ -31,6 +31,7 @@ enum async_op
ASYNC_START, ASYNC_START,
ASYNC_STOP, ASYNC_STOP,
ASYNC_PAUSE, ASYNC_PAUSE,
ASYNC_PROCESS,
}; };
struct async_command struct async_command
...@@ -39,6 +40,15 @@ struct async_command ...@@ -39,6 +40,15 @@ struct async_command
LONG refcount; LONG refcount;
enum async_op op; enum async_op op;
union
{
struct
{
IMFSample *sample;
UINT32 stream_id;
} process;
} u;
}; };
struct stream_sink struct stream_sink
...@@ -142,7 +152,11 @@ static ULONG WINAPI async_command_Release(IUnknown *iface) ...@@ -142,7 +152,11 @@ static ULONG WINAPI async_command_Release(IUnknown *iface)
ULONG refcount = InterlockedDecrement(&command->refcount); ULONG refcount = InterlockedDecrement(&command->refcount);
if (!refcount) if (!refcount)
{
if (command->op == ASYNC_PROCESS && command->u.process.sample)
IMFSample_Release(command->u.process.sample);
free(command); free(command);
}
return refcount; return refcount;
} }
...@@ -301,9 +315,41 @@ static HRESULT WINAPI stream_sink_GetMediaTypeHandler(IMFStreamSink *iface, IMFM ...@@ -301,9 +315,41 @@ static HRESULT WINAPI stream_sink_GetMediaTypeHandler(IMFStreamSink *iface, IMFM
static HRESULT WINAPI stream_sink_ProcessSample(IMFStreamSink *iface, IMFSample *sample) static HRESULT WINAPI stream_sink_ProcessSample(IMFStreamSink *iface, IMFSample *sample)
{ {
FIXME("iface %p, sample %p stub!\n", iface, sample); struct stream_sink *stream_sink = impl_from_IMFStreamSink(iface);
struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(stream_sink->media_sink);
struct async_command *command;
HRESULT hr;
return E_NOTIMPL; TRACE("iface %p, sample %p.\n", iface, sample);
EnterCriticalSection(&media_sink->cs);
if (media_sink->state == STATE_SHUTDOWN)
{
LeaveCriticalSection(&media_sink->cs);
return MF_E_SHUTDOWN;
}
if (media_sink->state != STATE_STARTED && media_sink->state != STATE_PAUSED)
{
LeaveCriticalSection(&media_sink->cs);
return MF_E_INVALIDREQUEST;
}
if (FAILED(hr = (async_command_create(ASYNC_PROCESS, &command))))
{
LeaveCriticalSection(&media_sink->cs);
return hr;
}
IMFSample_AddRef((command->u.process.sample = sample));
command->u.process.stream_id = stream_sink->id;
if (FAILED(hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &media_sink->async_callback, &command->IUnknown_iface)))
IUnknown_Release(&command->IUnknown_iface);
LeaveCriticalSection(&media_sink->cs);
return hr;
} }
static HRESULT WINAPI stream_sink_PlaceMarker(IMFStreamSink *iface, MFSTREAMSINK_MARKER_TYPE marker_type, static HRESULT WINAPI stream_sink_PlaceMarker(IMFStreamSink *iface, MFSTREAMSINK_MARKER_TYPE marker_type,
...@@ -521,6 +567,40 @@ static HRESULT media_sink_pause(struct media_sink *media_sink) ...@@ -521,6 +567,40 @@ static HRESULT media_sink_pause(struct media_sink *media_sink)
return media_sink_queue_stream_event(media_sink, MEStreamSinkPaused); return media_sink_queue_stream_event(media_sink, MEStreamSinkPaused);
} }
static HRESULT media_sink_process(struct media_sink *media_sink, IMFSample *sample, UINT32 stream_id)
{
wg_muxer_t muxer = media_sink->muxer;
struct wg_sample *wg_sample;
LONGLONG time, duration;
UINT32 value;
HRESULT hr;
TRACE("media_sink %p, sample %p, stream_id %u.\n", media_sink, sample, stream_id);
if (FAILED(hr = wg_sample_create_mf(sample, &wg_sample)))
return hr;
if (SUCCEEDED(IMFSample_GetSampleTime(sample, &time)))
{
wg_sample->flags |= WG_SAMPLE_FLAG_HAS_PTS;
wg_sample->pts = time;
}
if (SUCCEEDED(IMFSample_GetSampleDuration(sample, &duration)))
{
wg_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION;
wg_sample->duration = duration;
}
if (SUCCEEDED(IMFSample_GetUINT32(sample, &MFSampleExtension_CleanPoint, &value)) && value)
wg_sample->flags |= WG_SAMPLE_FLAG_SYNC_POINT;
if (SUCCEEDED(IMFSample_GetUINT32(sample, &MFSampleExtension_Discontinuity, &value)) && value)
wg_sample->flags |= WG_SAMPLE_FLAG_DISCONTINUITY;
hr = wg_muxer_push_sample(muxer, wg_sample, stream_id);
wg_sample_release(wg_sample);
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);
...@@ -1022,6 +1102,10 @@ static HRESULT WINAPI media_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsy ...@@ -1022,6 +1102,10 @@ static HRESULT WINAPI media_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsy
case ASYNC_PAUSE: case ASYNC_PAUSE:
hr = media_sink_pause(media_sink); hr = media_sink_pause(media_sink);
break; break;
case ASYNC_PROCESS:
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);
break;
default: default:
WARN("Unsupported op %u.\n", command->op); WARN("Unsupported op %u.\n", command->op);
break; break;
......
...@@ -69,6 +69,7 @@ extern NTSTATUS wg_muxer_create(void *args) DECLSPEC_HIDDEN; ...@@ -69,6 +69,7 @@ extern NTSTATUS wg_muxer_create(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_destroy(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_muxer_destroy(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_add_stream(void *args) DECLSPEC_HIDDEN; 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;
/* wg_allocator.c */ /* wg_allocator.c */
......
...@@ -385,6 +385,13 @@ struct wg_muxer_add_stream_params ...@@ -385,6 +385,13 @@ struct wg_muxer_add_stream_params
const struct wg_format *format; const struct wg_format *format;
}; };
struct wg_muxer_push_sample_params
{
wg_muxer_t muxer;
struct wg_sample *sample;
UINT32 stream_id;
};
enum unix_funcs enum unix_funcs
{ {
unix_wg_init_gstreamer, unix_wg_init_gstreamer,
...@@ -429,6 +436,7 @@ enum unix_funcs ...@@ -429,6 +436,7 @@ enum unix_funcs
unix_wg_muxer_destroy, unix_wg_muxer_destroy,
unix_wg_muxer_add_stream, unix_wg_muxer_add_stream,
unix_wg_muxer_start, unix_wg_muxer_start,
unix_wg_muxer_push_sample,
unix_wg_funcs_count, unix_wg_funcs_count,
}; };
......
...@@ -343,3 +343,8 @@ NTSTATUS wg_muxer_start(void *args) ...@@ -343,3 +343,8 @@ NTSTATUS wg_muxer_start(void *args)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS wg_muxer_push_sample(void *args)
{
return STATUS_NOT_IMPLEMENTED;
}
...@@ -1923,6 +1923,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = ...@@ -1923,6 +1923,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_muxer_destroy), X(wg_muxer_destroy),
X(wg_muxer_add_stream), X(wg_muxer_add_stream),
X(wg_muxer_start), X(wg_muxer_start),
X(wg_muxer_push_sample),
}; };
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count); C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count);
...@@ -2166,6 +2167,23 @@ NTSTATUS wow64_wg_muxer_add_stream(void *args) ...@@ -2166,6 +2167,23 @@ NTSTATUS wow64_wg_muxer_add_stream(void *args)
return wg_muxer_add_stream(&params); return wg_muxer_add_stream(&params);
} }
NTSTATUS wow64_wg_muxer_push_sample(void *args)
{
struct
{
wg_muxer_t muxer;
PTR32 sample;
UINT32 stream_id;
} *params32 = args;
struct wg_muxer_push_sample_params params =
{
.muxer = params32->muxer,
.sample = ULongToPtr(params32->sample),
.stream_id = params32->stream_id,
};
return wg_muxer_push_sample(&params);
}
const unixlib_entry_t __wine_unix_call_wow64_funcs[] = const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
{ {
#define X64(name) [unix_ ## name] = wow64_ ## name #define X64(name) [unix_ ## name] = wow64_ ## name
...@@ -2211,6 +2229,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = ...@@ -2211,6 +2229,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
X(wg_muxer_destroy), X(wg_muxer_destroy),
X64(wg_muxer_add_stream), X64(wg_muxer_add_stream),
X(wg_muxer_start), X(wg_muxer_start),
X64(wg_muxer_push_sample),
}; };
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