winegstreamer: Read samples synchronously in push_data().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5c057693c8
commit
c90a36e38c
|
@ -227,15 +227,6 @@ void unknown_type_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer
|
||||||
call_cb(&cbdata);
|
call_cb(&cbdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void release_sample_wrapper(gpointer data)
|
|
||||||
{
|
|
||||||
struct cb_data cbdata = { RELEASE_SAMPLE };
|
|
||||||
|
|
||||||
cbdata.u.release_sample_data.data = data;
|
|
||||||
|
|
||||||
call_cb(&cbdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query)
|
gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query)
|
||||||
{
|
{
|
||||||
struct cb_data cbdata = { QUERY_SINK };
|
struct cb_data cbdata = { QUERY_SINK };
|
||||||
|
|
|
@ -42,7 +42,6 @@ enum CB_TYPE {
|
||||||
REMOVED_DECODED_PAD,
|
REMOVED_DECODED_PAD,
|
||||||
AUTOPLUG_BLACKLIST,
|
AUTOPLUG_BLACKLIST,
|
||||||
UNKNOWN_TYPE,
|
UNKNOWN_TYPE,
|
||||||
RELEASE_SAMPLE,
|
|
||||||
QUERY_SINK
|
QUERY_SINK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,9 +121,6 @@ struct cb_data {
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
gpointer user;
|
gpointer user;
|
||||||
} unknown_type_data;
|
} unknown_type_data;
|
||||||
struct release_sample_data {
|
|
||||||
gpointer data;
|
|
||||||
} release_sample_data;
|
|
||||||
struct query_sink_data {
|
struct query_sink_data {
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
GstObject *parent;
|
GstObject *parent;
|
||||||
|
@ -159,7 +155,6 @@ GstFlowReturn got_data_wrapper(GstPad *pad, GstObject *parent, GstBuffer *buf) D
|
||||||
void removed_decoded_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN;
|
void removed_decoded_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN;
|
||||||
GstAutoplugSelectResult autoplug_blacklist_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *fact, gpointer user) DECLSPEC_HIDDEN;
|
GstAutoplugSelectResult autoplug_blacklist_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *fact, gpointer user) DECLSPEC_HIDDEN;
|
||||||
void unknown_type_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) DECLSPEC_HIDDEN;
|
void unknown_type_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) DECLSPEC_HIDDEN;
|
||||||
void release_sample_wrapper(gpointer data) DECLSPEC_HIDDEN;
|
|
||||||
void Gstreamer_transform_pad_added_wrapper(GstElement *filter, GstPad *pad, gpointer user) DECLSPEC_HIDDEN;
|
void Gstreamer_transform_pad_added_wrapper(GstElement *filter, GstPad *pad, gpointer user) DECLSPEC_HIDDEN;
|
||||||
gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN;
|
gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -97,8 +97,6 @@ static inline struct gstdemux *impl_from_strmbase_filter(struct strmbase_filter
|
||||||
return CONTAINING_RECORD(iface, struct gstdemux, filter);
|
return CONTAINING_RECORD(iface, struct gstdemux, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *media_quark_string = "media-sample";
|
|
||||||
|
|
||||||
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
|
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
|
||||||
static const IMediaSeekingVtbl GST_Seeking_Vtbl;
|
static const IMediaSeekingVtbl GST_Seeking_Vtbl;
|
||||||
static const IQualityControlVtbl GSTOutPin_QualityControl_Vtbl;
|
static const IQualityControlVtbl GSTOutPin_QualityControl_Vtbl;
|
||||||
|
@ -744,21 +742,20 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_sample(void *data)
|
|
||||||
{
|
|
||||||
ULONG ret;
|
|
||||||
ret = IMediaSample_Release((IMediaSample *)data);
|
|
||||||
TRACE("Releasing %p returns %u\n", data, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD CALLBACK push_data(LPVOID iface)
|
static DWORD CALLBACK push_data(LPVOID iface)
|
||||||
{
|
{
|
||||||
LONGLONG maxlen, curlen;
|
LONGLONG maxlen, curlen;
|
||||||
struct gstdemux *This = iface;
|
struct gstdemux *This = iface;
|
||||||
IMediaSample *buf;
|
GstMapInfo mapping;
|
||||||
DWORD_PTR user;
|
GstBuffer *buffer;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!(buffer = gst_buffer_new_allocate(NULL, 16384, NULL)))
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate memory.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
|
IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
|
||||||
|
|
||||||
if (!This->stop)
|
if (!This->stop)
|
||||||
|
@ -768,51 +765,30 @@ static DWORD CALLBACK push_data(LPVOID iface)
|
||||||
|
|
||||||
TRACE("Starting..\n");
|
TRACE("Starting..\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
REFERENCE_TIME tStart, tStop;
|
|
||||||
ULONG len;
|
ULONG len;
|
||||||
GstBuffer *gstbuf;
|
|
||||||
gsize bufsize;
|
|
||||||
BYTE *data;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
hr = IMemAllocator_GetBuffer(This->alloc, &buf, NULL, NULL, 0);
|
|
||||||
if (FAILED(hr))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (This->nextofs >= maxlen)
|
if (This->nextofs >= maxlen)
|
||||||
break;
|
break;
|
||||||
len = IMediaSample_GetSize(buf);
|
len = min(16384, maxlen - This->nextofs);
|
||||||
if (This->nextofs + len > maxlen)
|
|
||||||
len = maxlen - This->nextofs;
|
|
||||||
|
|
||||||
tStart = MEDIATIME_FROM_BYTES(This->nextofs);
|
if (!gst_buffer_map_range(buffer, -1, len, &mapping, GST_MAP_WRITE))
|
||||||
tStop = tStart + MEDIATIME_FROM_BYTES(len);
|
{
|
||||||
IMediaSample_SetTime(buf, &tStart, &tStop);
|
ERR("Failed to map buffer.\n");
|
||||||
|
|
||||||
hr = IAsyncReader_Request(This->reader, buf, 0);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
IMediaSample_Release(buf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
hr = IAsyncReader_SyncRead(This->reader, This->nextofs, len, mapping.data);
|
||||||
|
gst_buffer_unmap(buffer, &mapping);
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
ERR("Failed to read data, hr %#x.\n", hr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
This->nextofs += len;
|
This->nextofs += len;
|
||||||
hr = IAsyncReader_WaitForNext(This->reader, -1, &buf, &user);
|
|
||||||
if (FAILED(hr) || !buf) {
|
|
||||||
if (buf)
|
|
||||||
IMediaSample_Release(buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMediaSample_GetPointer(buf, &data);
|
buffer->duration = buffer->pts = -1;
|
||||||
bufsize = IMediaSample_GetActualDataLength(buf);
|
ret = gst_pad_push(This->my_src, buffer);
|
||||||
gstbuf = gst_buffer_new_wrapped_full(0, data, bufsize, 0, bufsize, buf, release_sample_wrapper);
|
|
||||||
IMediaSample_AddRef(buf);
|
|
||||||
gst_mini_object_set_qdata(GST_MINI_OBJECT(gstbuf), g_quark_from_static_string(media_quark_string), buf, release_sample_wrapper);
|
|
||||||
if (!gstbuf) {
|
|
||||||
IMediaSample_Release(buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gstbuf->duration = gstbuf->pts = -1;
|
|
||||||
ret = gst_pad_push(This->my_src, gstbuf);
|
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
else
|
else
|
||||||
|
@ -825,14 +801,9 @@ static DWORD CALLBACK push_data(LPVOID iface)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_pad_push_event(This->my_src, gst_event_new_eos());
|
gst_buffer_unref(buffer);
|
||||||
|
|
||||||
TRACE("Almost stopping.. %08x\n", hr);
|
gst_pad_push_event(This->my_src, gst_event_new_eos());
|
||||||
do {
|
|
||||||
IAsyncReader_WaitForNext(This->reader, 0, &buf, &user);
|
|
||||||
if (buf)
|
|
||||||
IMediaSample_Release(buf);
|
|
||||||
} while (buf);
|
|
||||||
|
|
||||||
TRACE("Stopping.. %08x\n", hr);
|
TRACE("Stopping.. %08x\n", hr);
|
||||||
|
|
||||||
|
@ -2332,12 +2303,6 @@ void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user)
|
||||||
unknown_type(data->bin, data->pad, data->caps, data->user);
|
unknown_type(data->bin, data->pad, data->caps, data->user);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RELEASE_SAMPLE:
|
|
||||||
{
|
|
||||||
struct release_sample_data *data = &cbdata->u.release_sample_data;
|
|
||||||
release_sample(data->data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_SINK:
|
case QUERY_SINK:
|
||||||
{
|
{
|
||||||
struct query_sink_data *data = &cbdata->u.query_sink_data;
|
struct query_sink_data *data = &cbdata->u.query_sink_data;
|
||||||
|
|
Loading…
Reference in New Issue