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);
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_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_max_size(const struct wg_format *format);
......
......@@ -523,6 +523,27 @@ HRESULT wg_muxer_start(wg_muxer_t muxer)
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))
unsigned int wg_format_get_stride(const struct wg_format *format)
......
......@@ -31,6 +31,7 @@ enum async_op
ASYNC_START,
ASYNC_STOP,
ASYNC_PAUSE,
ASYNC_PROCESS,
};
struct async_command
......@@ -39,6 +40,15 @@ struct async_command
LONG refcount;
enum async_op op;
union
{
struct
{
IMFSample *sample;
UINT32 stream_id;
} process;
} u;
};
struct stream_sink
......@@ -142,7 +152,11 @@ static ULONG WINAPI async_command_Release(IUnknown *iface)
ULONG refcount = InterlockedDecrement(&command->refcount);
if (!refcount)
{
if (command->op == ASYNC_PROCESS && command->u.process.sample)
IMFSample_Release(command->u.process.sample);
free(command);
}
return refcount;
}
......@@ -301,9 +315,41 @@ static HRESULT WINAPI stream_sink_GetMediaTypeHandler(IMFStreamSink *iface, IMFM
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,
......@@ -521,6 +567,40 @@ static HRESULT media_sink_pause(struct media_sink *media_sink)
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)
{
struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface);
......@@ -1022,6 +1102,10 @@ static HRESULT WINAPI media_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsy
case ASYNC_PAUSE:
hr = media_sink_pause(media_sink);
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:
WARN("Unsupported op %u.\n", command->op);
break;
......
......@@ -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_add_stream(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 */
......
......@@ -385,6 +385,13 @@ struct wg_muxer_add_stream_params
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
{
unix_wg_init_gstreamer,
......@@ -429,6 +436,7 @@ enum unix_funcs
unix_wg_muxer_destroy,
unix_wg_muxer_add_stream,
unix_wg_muxer_start,
unix_wg_muxer_push_sample,
unix_wg_funcs_count,
};
......
......@@ -343,3 +343,8 @@ NTSTATUS wg_muxer_start(void *args)
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[] =
X(wg_muxer_destroy),
X(wg_muxer_add_stream),
X(wg_muxer_start),
X(wg_muxer_push_sample),
};
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count);
......@@ -2166,6 +2167,23 @@ NTSTATUS wow64_wg_muxer_add_stream(void *args)
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[] =
{
#define X64(name) [unix_ ## name] = wow64_ ## name
......@@ -2211,6 +2229,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
X(wg_muxer_destroy),
X64(wg_muxer_add_stream),
X(wg_muxer_start),
X64(wg_muxer_push_sample),
};
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