mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 22:50:43 +00:00
winegstreamer: Move seeking from filter to pins.
This commit is contained in:
parent
9ce718d0e9
commit
d82d3d074b
@ -57,7 +57,6 @@ typedef struct GSTImpl {
|
|||||||
GSTInPin pInputPin;
|
GSTInPin pInputPin;
|
||||||
GSTOutPin **ppPins;
|
GSTOutPin **ppPins;
|
||||||
LONG cStreams;
|
LONG cStreams;
|
||||||
SourceSeeking sourceSeeking;
|
|
||||||
|
|
||||||
LONGLONG filesize;
|
LONGLONG filesize;
|
||||||
|
|
||||||
@ -81,6 +80,7 @@ struct GSTOutPin {
|
|||||||
AM_MEDIA_TYPE * pmt;
|
AM_MEDIA_TYPE * pmt;
|
||||||
HANDLE caps_event;
|
HANDLE caps_event;
|
||||||
GstSegment *segment;
|
GstSegment *segment;
|
||||||
|
SourceSeeking seek;
|
||||||
};
|
};
|
||||||
|
|
||||||
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};
|
||||||
@ -544,6 +544,7 @@ static GstFlowReturn got_data_sink(GstPad *pad, GstBuffer *buf) {
|
|||||||
rtStop = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->timestamp + buf->duration);
|
rtStop = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->timestamp + buf->duration);
|
||||||
if (rtStop >= 0)
|
if (rtStop >= 0)
|
||||||
rtStop /= 100;
|
rtStop /= 100;
|
||||||
|
TRACE("Current time on %p: %i to %i ms\n", pin, (int)(rtStart / 10000), (int)(rtStop / 10000));
|
||||||
IMediaSample_SetTime(sample, &rtStart, rtStop >= 0 ? &rtStop : NULL);
|
IMediaSample_SetTime(sample, &rtStart, rtStop >= 0 ? &rtStop : NULL);
|
||||||
IMediaSample_SetMediaTime(sample, &tStart, &tStop);
|
IMediaSample_SetMediaTime(sample, &tStart, &tStop);
|
||||||
} else {
|
} else {
|
||||||
@ -876,7 +877,7 @@ static HRESULT GST_Connect(GSTInPin *pPin, IPin *pConnectPin, ALLOCATOR_PROPERTI
|
|||||||
GSTImpl *This = (GSTImpl*)pPin->pin.pinInfo.pFilter;
|
GSTImpl *This = (GSTImpl*)pPin->pin.pinInfo.pFilter;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
LONGLONG avail;
|
LONGLONG avail, duration;
|
||||||
GstFormat format = GST_FORMAT_TIME;
|
GstFormat format = GST_FORMAT_TIME;
|
||||||
GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE(
|
GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE(
|
||||||
"quartz_src",
|
"quartz_src",
|
||||||
@ -931,28 +932,24 @@ static HRESULT GST_Connect(GSTInPin *pPin, IPin *pConnectPin, ALLOCATOR_PROPERTI
|
|||||||
FIXME("Gstreamer could not find any streams\n");
|
FIXME("Gstreamer could not find any streams\n");
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < This->cStreams; ++i)
|
gst_pad_query_duration(This->ppPins[0]->their_src, &format, &duration);
|
||||||
|
for (i = 0; i < This->cStreams; ++i) {
|
||||||
|
This->ppPins[i]->seek.llDuration = This->ppPins[i]->seek.llStop = duration / 100;
|
||||||
WaitForSingleObject(This->ppPins[i]->caps_event, -1);
|
WaitForSingleObject(This->ppPins[i]->caps_event, -1);
|
||||||
|
}
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
}
|
}
|
||||||
*props = This->props;
|
*props = This->props;
|
||||||
gst_pad_query_duration(This->ppPins[0]->their_src, &format, &This->sourceSeeking.llDuration);
|
|
||||||
This->sourceSeeking.llDuration /= 100;
|
|
||||||
gst_element_set_state(This->gstfilter, GST_STATE_READY);
|
gst_element_set_state(This->gstfilter, GST_STATE_READY);
|
||||||
gst_element_get_state(This->gstfilter, NULL, NULL, -1);
|
gst_element_get_state(This->gstfilter, NULL, NULL, -1);
|
||||||
|
|
||||||
This->initial = 0;
|
This->initial = 0;
|
||||||
This->nextofs = This->nextpullofs = 0;
|
This->nextofs = This->nextpullofs = 0;
|
||||||
|
|
||||||
GST_ChangeCurrent((IMediaSeeking*)&This->sourceSeeking);
|
|
||||||
|
|
||||||
This->sourceSeeking.llCurrent = 0;
|
|
||||||
This->sourceSeeking.llStop = This->sourceSeeking.llDuration;
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline GSTImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) {
|
static inline GSTOutPin *impl_from_IMediaSeeking( IMediaSeeking *iface ) {
|
||||||
return (GSTImpl *)((char*)iface - FIELD_OFFSET(GSTImpl, sourceSeeking.lpVtbl));
|
return (GSTOutPin *)((char*)iface - FIELD_OFFSET(GSTOutPin, seek.lpVtbl));
|
||||||
}
|
}
|
||||||
|
|
||||||
static IPin* WINAPI GST_GetPin(BaseFilter *iface, int pos)
|
static IPin* WINAPI GST_GetPin(BaseFilter *iface, int pos)
|
||||||
@ -1011,8 +1008,6 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *punkout, HRESULT *phr) {
|
|||||||
This->push_thread = NULL;
|
This->push_thread = NULL;
|
||||||
This->event = CreateEventW(NULL, 0, 0, NULL);
|
This->event = CreateEventW(NULL, 0, 0, NULL);
|
||||||
|
|
||||||
SourceSeeking_Init(&This->sourceSeeking, &GST_Seeking_Vtbl, GST_ChangeStop, GST_ChangeCurrent, GST_ChangeRate, &This->filter.csFilter);
|
|
||||||
|
|
||||||
piInput = &This->pInputPin.pin.pinInfo;
|
piInput = &This->pInputPin.pin.pinInfo;
|
||||||
piInput->dir = PINDIR_INPUT;
|
piInput->dir = PINDIR_INPUT;
|
||||||
piInput->pFilter = (IBaseFilter *)This;
|
piInput->pFilter = (IBaseFilter *)This;
|
||||||
@ -1067,15 +1062,14 @@ static HRESULT WINAPI GST_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID
|
|||||||
*ppv = This;
|
*ppv = This;
|
||||||
else if (IsEqualIID(riid, &IID_IBaseFilter))
|
else if (IsEqualIID(riid, &IID_IBaseFilter))
|
||||||
*ppv = This;
|
*ppv = This;
|
||||||
else if (IsEqualIID(riid, &IID_IMediaSeeking))
|
|
||||||
*ppv = &This->sourceSeeking;
|
|
||||||
|
|
||||||
if (*ppv) {
|
if (*ppv) {
|
||||||
IUnknown_AddRef((IUnknown *)(*ppv));
|
IUnknown_AddRef((IUnknown *)(*ppv));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow))
|
if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow) &&
|
||||||
|
!IsEqualIID(riid, &IID_IAMFilterMiscFlags))
|
||||||
FIXME("No interface for %s!\n", debugstr_guid(riid));
|
FIXME("No interface for %s!\n", debugstr_guid(riid));
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
@ -1226,59 +1220,41 @@ static const IBaseFilterVtbl GST_Vtbl = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface) {
|
static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface) {
|
||||||
GSTImpl *This = impl_from_IMediaSeeking(iface);
|
GSTOutPin *This = impl_from_IMediaSeeking(iface);
|
||||||
int i;
|
GstEvent *ev = gst_event_new_seek(This->seek.dRate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, This->seek.llCurrent * 100, GST_SEEK_TYPE_NONE, -1);
|
||||||
GstEvent *ev = gst_event_new_seek(This->sourceSeeking.dRate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, This->sourceSeeking.llCurrent * 100, GST_SEEK_TYPE_NONE, -1);
|
TRACE("(%p) going to %i.%i!\n", iface, (int)(This->seek.llCurrent / 10000000), (int)((This->seek.llCurrent / 10000)%1000));
|
||||||
FIXME("(%p) filter hasn't implemented current position change, going to %i.%i!\n", iface, (int)(This->sourceSeeking.llCurrent / 10000000), (int)((This->sourceSeeking.llCurrent / 10000)%1000));
|
gst_pad_push_event(This->my_sink, ev);
|
||||||
for (i = 0; i < This->cStreams; ++i) {
|
|
||||||
GstPad *pad = This->ppPins[i]->my_sink;
|
|
||||||
gst_event_ref(ev);
|
|
||||||
gst_pad_push_event(pad, ev);
|
|
||||||
}
|
|
||||||
gst_event_unref(ev);
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface) {
|
static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface) {
|
||||||
GSTImpl *This = impl_from_IMediaSeeking(iface);
|
GSTOutPin *This = impl_from_IMediaSeeking(iface);
|
||||||
int i;
|
GstEvent *ev = gst_event_new_seek(This->seek.dRate, GST_FORMAT_TIME, 0, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, This->seek.llStop);
|
||||||
GstEvent *ev = gst_event_new_seek(This->sourceSeeking.dRate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, This->sourceSeeking.llStop * 100);
|
TRACE("(%p) going to %i.%i!\n", iface, (int)(This->seek.llCurrent / 10000000), (int)((This->seek.llCurrent / 10000)%1000));
|
||||||
FIXME("(%p) filter hasn't implemented stop position change, going to %i.%i!\n", iface, (int)(This->sourceSeeking.llStop / 10000000), (int)((This->sourceSeeking.llStop / 10000)%1000));
|
gst_pad_push_event(This->my_sink, ev);
|
||||||
for (i = 0; i < This->cStreams; ++i) {
|
|
||||||
GstPad *pad = This->ppPins[i]->my_sink;
|
|
||||||
gst_event_ref(ev);
|
|
||||||
gst_pad_push_event(pad, ev);
|
|
||||||
}
|
|
||||||
gst_event_unref(ev);
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface) {
|
static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface) {
|
||||||
GSTImpl *This = impl_from_IMediaSeeking(iface);
|
GSTOutPin *This = impl_from_IMediaSeeking(iface);
|
||||||
int i;
|
GstEvent *ev = gst_event_new_seek(This->seek.dRate, GST_FORMAT_TIME, 0, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1);
|
||||||
GstEvent *ev = gst_event_new_seek(This->sourceSeeking.dRate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1);
|
TRACE("(%p) New rate %g\n", iface, This->seek.dRate);
|
||||||
FIXME("(%p) filter hasn't implemented rate change! Going to %g\n", iface, This->sourceSeeking.dRate);
|
gst_pad_push_event(This->my_sink, ev);
|
||||||
for (i = 0; i < This->cStreams; ++i) {
|
|
||||||
GstPad *pad = This->ppPins[i]->my_sink;
|
|
||||||
gst_event_ref(ev);
|
|
||||||
gst_pad_push_event(pad, ev);
|
|
||||||
}
|
|
||||||
gst_event_unref(ev);
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI GST_Seeking_QueryInterface(IMediaSeeking *iface, REFIID riid, void **ppv) {
|
static HRESULT WINAPI GST_Seeking_QueryInterface(IMediaSeeking *iface, REFIID riid, void **ppv) {
|
||||||
GSTImpl *This = impl_from_IMediaSeeking(iface);
|
GSTOutPin *This = impl_from_IMediaSeeking(iface);
|
||||||
return IUnknown_QueryInterface((IUnknown *)This, riid, ppv);
|
return IUnknown_QueryInterface((IUnknown *)This, riid, ppv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI GST_Seeking_AddRef(IMediaSeeking *iface) {
|
static ULONG WINAPI GST_Seeking_AddRef(IMediaSeeking *iface) {
|
||||||
GSTImpl *This = impl_from_IMediaSeeking(iface);
|
GSTOutPin *This = impl_from_IMediaSeeking(iface);
|
||||||
return IUnknown_AddRef((IUnknown *)This);
|
return IUnknown_AddRef((IUnknown *)This);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI GST_Seeking_Release(IMediaSeeking *iface) {
|
static ULONG WINAPI GST_Seeking_Release(IMediaSeeking *iface) {
|
||||||
GSTImpl *This = impl_from_IMediaSeeking(iface);
|
GSTOutPin *This = impl_from_IMediaSeeking(iface);
|
||||||
return IUnknown_Release((IUnknown *)This);
|
return IUnknown_Release((IUnknown *)This);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1318,7 +1294,7 @@ static HRESULT WINAPI GSTOutPin_QueryInterface(IPin *iface, REFIID riid, void **
|
|||||||
else if (IsEqualIID(riid, &IID_IPin))
|
else if (IsEqualIID(riid, &IID_IPin))
|
||||||
*ppv = iface;
|
*ppv = iface;
|
||||||
else if (IsEqualIID(riid, &IID_IMediaSeeking))
|
else if (IsEqualIID(riid, &IID_IMediaSeeking))
|
||||||
return IBaseFilter_QueryInterface(This->pin.pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv);
|
*ppv = &This->seek;
|
||||||
|
|
||||||
if (*ppv) {
|
if (*ppv) {
|
||||||
IUnknown_AddRef((IUnknown *)(*ppv));
|
IUnknown_AddRef((IUnknown *)(*ppv));
|
||||||
@ -1446,6 +1422,7 @@ static HRESULT GST_AddPin(GSTImpl *This, const PIN_INFO *piOutput, const AM_MEDI
|
|||||||
pin->caps_event = CreateEventW(NULL, 0, 0, NULL);
|
pin->caps_event = CreateEventW(NULL, 0, 0, NULL);
|
||||||
pin->segment = gst_segment_new();
|
pin->segment = gst_segment_new();
|
||||||
This->cStreams++;
|
This->cStreams++;
|
||||||
|
SourceSeeking_Init(&pin->seek, &GST_Seeking_Vtbl, GST_ChangeStop, GST_ChangeCurrent, GST_ChangeRate, &This->filter.csFilter);
|
||||||
BaseFilterImpl_IncrementPinVersion((BaseFilter*)This);
|
BaseFilterImpl_IncrementPinVersion((BaseFilter*)This);
|
||||||
} else
|
} else
|
||||||
ERR("Failed with error %x\n", hr);
|
ERR("Failed with error %x\n", hr);
|
||||||
|
Loading…
Reference in New Issue
Block a user