Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/avimux.c | 193 +++++++++++++++++++++------------------------ 1 file changed, 92 insertions(+), 101 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c index 9dcff5074e6..784d93a57c4 100644 --- a/dlls/qcap/avimux.c +++ b/dlls/qcap/avimux.c @@ -39,22 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(qcap); #define AVISTDINDEX_ENTRIES 4000 #define ALIGN(x) ((x+1)/2*2)
-typedef struct { - BaseOutputPin pin; - IQualityControl IQualityControl_iface; - - int cur_stream; - LONGLONG cur_time; - - int buf_pos; - BYTE buf[65536]; - - int movi_off; - int out_pos; - int size; - IStream *stream; -} AviMuxOut; - typedef struct { BaseInputPin pin; IAMStreamControl IAMStreamControl_iface; @@ -97,7 +81,9 @@ typedef struct { REFERENCE_TIME interleave; REFERENCE_TIME preroll;
- AviMuxOut *out; + BaseOutputPin source; + IQualityControl IQualityControl_iface; + int input_pin_no; AviMuxIn *in[MAX_PIN_NO-1];
@@ -107,6 +93,17 @@ typedef struct { int idx1_entries; int idx1_size; AVIINDEXENTRY *idx1; + + int cur_stream; + LONGLONG cur_time; + + int buf_pos; + BYTE buf[65536]; + + int movi_off; + int out_pos; + int size; + IStream *stream; } AviMux;
static HRESULT create_input_pin(AviMux*); @@ -121,7 +118,7 @@ static IPin *avi_mux_get_pin(BaseFilter *iface, unsigned int index) AviMux *filter = impl_from_BaseFilter(iface);
if (!index) - return &filter->out->pin.pin.IPin_iface; + return &filter->source.pin.IPin_iface; else if (index <= filter->input_pin_no) return &filter->in[index - 1]->pin.pin.IPin_iface; return NULL; @@ -132,7 +129,7 @@ static void avi_mux_destroy(BaseFilter *iface) AviMux *filter = impl_from_BaseFilter(iface); int i;
- BaseOutputPinImpl_Release(&filter->out->pin.pin.IPin_iface); + strmbase_source_cleanup(&filter->source);
for (i = 0; i < filter->input_pin_no; ++i) { @@ -187,16 +184,16 @@ static HRESULT out_flush(AviMux *This) ULONG written; HRESULT hr;
- if(!This->out->buf_pos) + if(!This->buf_pos) return S_OK;
- hr = IStream_Write(This->out->stream, This->out->buf, This->out->buf_pos, &written); + hr = IStream_Write(This->stream, This->buf, This->buf_pos, &written); if(FAILED(hr)) return hr; - if(written != This->out->buf_pos) + if (written != This->buf_pos) return E_FAIL;
- This->out->buf_pos = 0; + This->buf_pos = 0; return S_OK; }
@@ -210,13 +207,13 @@ static HRESULT out_seek(AviMux *This, int pos) return hr;
li.QuadPart = pos; - hr = IStream_Seek(This->out->stream, li, STREAM_SEEK_SET, NULL); + hr = IStream_Seek(This->stream, li, STREAM_SEEK_SET, NULL); if(FAILED(hr)) return hr;
- This->out->out_pos = pos; - if(This->out->out_pos > This->out->size) - This->out->size = This->out->out_pos; + This->out_pos = pos; + if(This->out_pos > This->size) + This->size = This->out_pos; return hr; }
@@ -226,18 +223,18 @@ static HRESULT out_write(AviMux *This, const void *data, int size) HRESULT hr;
while(1) { - if(size > sizeof(This->out->buf)-This->out->buf_pos) - chunk_size = sizeof(This->out->buf)-This->out->buf_pos; + if (size > sizeof(This->buf) - This->buf_pos) + chunk_size = sizeof(This->buf) - This->buf_pos; else chunk_size = size;
- memcpy(This->out->buf + This->out->buf_pos, data, chunk_size); + memcpy(This->buf + This->buf_pos, data, chunk_size); size -= chunk_size; data = (const BYTE*)data + chunk_size; - This->out->buf_pos += chunk_size; - This->out->out_pos += chunk_size; - if(This->out->out_pos > This->out->size) - This->out->size = This->out->out_pos; + This->buf_pos += chunk_size; + This->out_pos += chunk_size; + if (This->out_pos > This->size) + This->size = This->out_pos;
if(!size) break; @@ -278,7 +275,7 @@ static HRESULT flush_queue(AviMux *avimux, AviMuxIn *avimuxin, BOOL closing) DWORD flags; HRESULT hr;
- if(avimux->out->cur_stream != avimuxin->stream_id) + if (avimux->cur_stream != avimuxin->stream_id) return S_OK;
while(avimuxin->samples_head) { @@ -301,17 +298,18 @@ static HRESULT flush_queue(AviMux *avimux, AviMuxIn *avimuxin, BOOL closing) if(IMediaSample_IsSyncPoint(sample) == S_OK) flags |= AM_SAMPLE_SPLICEPOINT;
- if(avimuxin->stream_time + (closing ? 0 : avimuxin->strh.dwScale) > avimux->out->cur_time && - !(flags & AM_SAMPLE_TIMEDISCONTINUITY)) { + if (avimuxin->stream_time + (closing ? 0 : avimuxin->strh.dwScale) > avimux->cur_time + && !(flags & AM_SAMPLE_TIMEDISCONTINUITY)) + { if(closing) break;
- avimux->out->cur_stream++; - if(avimux->out->cur_stream >= avimux->input_pin_no-1) { - avimux->out->cur_time += avimux->interleave; - avimux->out->cur_stream = 0; + avimux->cur_stream++; + if(avimux->cur_stream >= avimux->input_pin_no-1) { + avimux->cur_time += avimux->interleave; + avimux->cur_stream = 0; } - avimuxin = avimux->in[avimux->out->cur_stream]; + avimuxin = avimux->in[avimux->cur_stream]; continue; }
@@ -333,8 +331,8 @@ static HRESULT flush_queue(AviMux *avimux, AviMuxIn *avimuxin, BOOL closing) avimuxin->ix->nEntriesInUse = 0; avimuxin->ix->qwBaseOffset = 0;
- avimuxin->ix_off = avimux->out->size; - avimux->out->size += sizeof(avimuxin->ix_data); + avimuxin->ix_off = avimux->size; + avimux->size += sizeof(avimuxin->ix_data); }
if(*head_prev == avimuxin->samples_head) @@ -346,11 +344,11 @@ static HRESULT flush_queue(AviMux *avimux, AviMuxIn *avimuxin, BOOL closing) avimuxin->strh.dwLength++; if(!(flags & AM_SAMPLE_TIMEDISCONTINUITY)) { if(!avimuxin->ix->qwBaseOffset) - avimuxin->ix->qwBaseOffset = avimux->out->size; - avimuxin->ix->aIndex[avimuxin->ix->nEntriesInUse].dwOffset = avimux->out->size - + sizeof(RIFFCHUNK) - avimuxin->ix->qwBaseOffset; + avimuxin->ix->qwBaseOffset = avimux->size; + avimuxin->ix->aIndex[avimuxin->ix->nEntriesInUse].dwOffset = + avimux->size + sizeof(RIFFCHUNK) - avimuxin->ix->qwBaseOffset;
- hr = out_seek(avimux, avimux->out->size); + hr = out_seek(avimux, avimux->size); if(FAILED(hr)) { IMediaSample_Release(sample); return hr; @@ -365,7 +363,7 @@ static HRESULT flush_queue(AviMux *avimux, AviMuxIn *avimuxin, BOOL closing) rf.cb = size; hr = idx1_add_entry(avimux, rf.fcc, flags & AM_SAMPLE_SPLICEPOINT ? AVIIF_KEYFRAME : 0, flags & AM_SAMPLE_TIMEDISCONTINUITY ? - avimux->idx1[avimux->idx1_entries-1].dwChunkOffset : avimux->out->size, size); + avimux->idx1[avimux->idx1_entries-1].dwChunkOffset : avimux->size, size); if(FAILED(hr)) { IMediaSample_Release(sample); return hr; @@ -432,26 +430,27 @@ static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface) if(This->filter.state == State_Stopped) return S_OK;
- if(This->out->stream) { + if (This->stream) + { AVIEXTHEADER dmlh; RIFFCHUNK rc; RIFFLIST rl; int idx1_off, empty_stream;
- empty_stream = This->out->cur_stream; + empty_stream = This->cur_stream; for(i=empty_stream+1; ; i++) { if(i >= This->input_pin_no-1) i = 0; if(i == empty_stream) break;
- This->out->cur_stream = i; - hr = flush_queue(This, This->in[This->out->cur_stream], TRUE); + This->cur_stream = i; + hr = flush_queue(This, This->in[This->cur_stream], TRUE); if(FAILED(hr)) return hr; }
- idx1_off = This->out->size; + idx1_off = This->size; rc.fcc = ckidAVIOLDINDEX; rc.cb = This->idx1_entries * sizeof(*This->idx1); hr = out_write(This, &rc, sizeof(rc)); @@ -495,14 +494,14 @@ static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface) return hr;
rl.fcc = FCC('R','I','F','F'); - rl.cb = This->out->size-sizeof(RIFFCHUNK)-2*sizeof(int); + rl.cb = This->size - sizeof(RIFFCHUNK) - 2 * sizeof(int); rl.fccListType = FCC('A','V','I',' '); hr = out_write(This, &rl, sizeof(rl)); if(FAILED(hr)) return hr;
rl.fcc = FCC('L','I','S','T'); - rl.cb = This->out->movi_off - sizeof(RIFFLIST) - sizeof(RIFFCHUNK); + rl.cb = This->movi_off - sizeof(RIFFLIST) - sizeof(RIFFCHUNK); rl.fccListType = FCC('h','d','r','l'); hr = out_write(This, &rl, sizeof(rl)); if(FAILED(hr)) @@ -550,13 +549,13 @@ static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface) dmlh.dwGrandFrames = This->in[0]->strh.dwLength; hr = out_write(This, &dmlh, sizeof(dmlh));
- rl.cb = idx1_off - This->out->movi_off - sizeof(RIFFCHUNK); + rl.cb = idx1_off - This->movi_off - sizeof(RIFFCHUNK); rl.fccListType = FCC('m','o','v','i'); out_write(This, &rl, sizeof(rl)); out_flush(This);
- IStream_Release(This->out->stream); - This->out->stream = NULL; + IStream_Release(This->stream); + This->stream = NULL; }
This->filter.state = State_Stopped; @@ -611,9 +610,10 @@ static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart) IMediaSeeking_Release(ms); }
- if(This->out->pin.pMemInputPin) { - hr = IMemInputPin_QueryInterface(This->out->pin.pMemInputPin, - &IID_IStream, (void**)&This->out->stream); + if (This->source.pMemInputPin) + { + hr = IMemInputPin_QueryInterface(This->source.pMemInputPin, + &IID_IStream, (void **)&This->stream); if(FAILED(hr)) return hr; } @@ -626,7 +626,7 @@ static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart) return E_OUTOFMEMORY; }
- This->out->size = 3*sizeof(RIFFLIST) + sizeof(AVIMAINHEADER) + sizeof(AVIEXTHEADER); + This->size = 3*sizeof(RIFFLIST) + sizeof(AVIMAINHEADER) + sizeof(AVIEXTHEADER); This->start = -1; This->stop = -1; memset(&This->avih, 0, sizeof(This->avih)); @@ -635,34 +635,35 @@ static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart) continue;
This->avih.dwStreams++; - This->out->size += sizeof(RIFFLIST) + sizeof(AVISTREAMHEADER) + sizeof(RIFFCHUNK) - + This->in[i]->strf->cb + sizeof(This->in[i]->indx_data); + This->size += sizeof(RIFFLIST) + sizeof(AVISTREAMHEADER) + sizeof(RIFFCHUNK) + + This->in[i]->strf->cb + sizeof(This->in[i]->indx_data);
This->in[i]->strh.dwScale = MulDiv(This->in[i]->avg_time_per_frame, This->interleave, 10000000); This->in[i]->strh.dwRate = This->interleave;
hr = IMemAllocator_Commit(This->in[i]->pin.pAllocator); if(FAILED(hr)) { - if(This->out->stream) { - IStream_Release(This->out->stream); - This->out->stream = NULL; + if (This->stream) + { + IStream_Release(This->stream); + This->stream = NULL; } return hr; } }
- This->out->movi_off = This->out->size; - This->out->size += sizeof(RIFFLIST); + This->movi_off = This->size; + This->size += sizeof(RIFFLIST);
- idx1_add_entry(This, FCC('7','F','x','x'), 0, This->out->movi_off+sizeof(RIFFLIST), 0); + idx1_add_entry(This, FCC('7','F','x','x'), 0, This->movi_off + sizeof(RIFFLIST), 0);
stream_id = 0; for(i=0; i<This->input_pin_no; i++) { if(!This->in[i]->pin.pin.pConnectedTo) continue;
- This->in[i]->ix_off = This->out->size; - This->out->size += sizeof(This->in[i]->ix_data); + This->in[i]->ix_off = This->size; + This->size += sizeof(This->in[i]->ix_data); This->in[i]->ix->fcc = FCC('i','x','0'+stream_id/10,'0'+stream_id%10); This->in[i]->ix->cb = sizeof(This->in[i]->ix_data) - sizeof(RIFFCHUNK); This->in[i]->ix->wLongsPerEntry = 2; @@ -680,8 +681,8 @@ static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart) This->in[i]->stream_id = stream_id++; }
- This->out->buf_pos = 0; - This->out->out_pos = 0; + This->buf_pos = 0; + This->out_pos = 0;
This->avih.fcc = ckidMAINAVIHEADER; This->avih.cb = sizeof(AVIMAINHEADER) - sizeof(RIFFCHUNK); @@ -813,9 +814,9 @@ static HRESULT WINAPI ConfigInterleaving_put_Mode( return E_INVALIDARG;
if(This->mode != mode) { - if(This->out->pin.pin.pConnectedTo) { + if(This->source.pin.pConnectedTo) { HRESULT hr = IFilterGraph_Reconnect(This->filter.filterInfo.pGraph, - &This->out->pin.pin.IPin_iface); + &This->source.pin.IPin_iface); if(FAILED(hr)) return hr; } @@ -1229,12 +1230,9 @@ static const BaseOutputPinFuncTable AviMuxOut_BaseOutputFuncTable = { AviMuxOut_DecideAllocator, };
-static inline AviMux* impl_from_out_IPin(IPin *iface) +static inline AviMux *impl_from_out_IPin(IPin *iface) { - BasePin *bp = CONTAINING_RECORD(iface, BasePin, IPin_iface); - IBaseFilter *bf = bp->pinInfo.pFilter; - - return impl_from_IBaseFilter(bf); + return CONTAINING_RECORD(iface, AviMux, source.pin.IPin_iface); }
static HRESULT WINAPI AviMuxOut_QueryInterface(IPin *iface, REFIID riid, void **ppv) @@ -1246,7 +1244,7 @@ static HRESULT WINAPI AviMuxOut_QueryInterface(IPin *iface, REFIID riid, void ** if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin)) *ppv = iface; else if(IsEqualIID(riid, &IID_IQualityControl)) - *ppv = &This->out->IQualityControl_iface; + *ppv = &This->IQualityControl_iface; else { FIXME("no interface for %s\n", debugstr_guid(riid)); *ppv = NULL; @@ -1431,15 +1429,14 @@ static const IPinVtbl AviMuxOut_PinVtbl = {
static inline AviMux* impl_from_out_IQualityControl(IQualityControl *iface) { - AviMuxOut *amo = CONTAINING_RECORD(iface, AviMuxOut, IQualityControl_iface); - return impl_from_IBaseFilter(amo->pin.pin.pinInfo.pFilter); + return CONTAINING_RECORD(iface, AviMux, IQualityControl_iface); }
static HRESULT WINAPI AviMuxOut_QualityControl_QueryInterface( IQualityControl *iface, REFIID riid, void **ppv) { AviMux *This = impl_from_out_IQualityControl(iface); - return IPin_QueryInterface(&This->out->pin.pin.IPin_iface, riid, ppv); + return IPin_QueryInterface(&This->source.pin.IPin_iface, riid, ppv); }
static ULONG WINAPI AviMuxOut_QualityControl_AddRef(IQualityControl *iface) @@ -2084,10 +2081,10 @@ static HRESULT WINAPI AviMuxIn_MemInputPin_ReceiveCanBlock(IMemInputPin *iface)
TRACE("(%p:%s)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName));
- if(!This->out->pin.pMemInputPin) + if(!This->source.pMemInputPin) return S_FALSE;
- hr = IMemInputPin_ReceiveCanBlock(This->out->pin.pMemInputPin); + hr = IMemInputPin_ReceiveCanBlock(This->source.pMemInputPin); return hr != S_FALSE ? S_OK : S_FALSE; }
@@ -2289,22 +2286,16 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr) info.dir = PINDIR_OUTPUT; info.pFilter = &avimux->filter.IBaseFilter_iface; lstrcpyW(info.achName, output_name); - hr = BaseOutputPin_Construct(&AviMuxOut_PinVtbl, sizeof(AviMuxOut), &info, - &AviMuxOut_BaseOutputFuncTable, &avimux->filter.csFilter, (IPin**)&avimux->out); - if(FAILED(hr)) { - strmbase_filter_cleanup(&avimux->filter); - HeapFree(GetProcessHeap(), 0, avimux); - *phr = hr; - return NULL; - } - avimux->out->IQualityControl_iface.lpVtbl = &AviMuxOut_QualityControlVtbl; - avimux->out->cur_stream = 0; - avimux->out->cur_time = 0; - avimux->out->stream = NULL; + strmbase_source_init(&avimux->source, &AviMuxOut_PinVtbl, &info, + &AviMuxOut_BaseOutputFuncTable, &avimux->filter.csFilter); + avimux->IQualityControl_iface.lpVtbl = &AviMuxOut_QualityControlVtbl; + avimux->cur_stream = 0; + avimux->cur_time = 0; + avimux->stream = NULL;
hr = create_input_pin(avimux); if(FAILED(hr)) { - BaseOutputPinImpl_Release(&avimux->out->pin.pin.IPin_iface); + strmbase_source_cleanup(&avimux->source); strmbase_filter_cleanup(&avimux->filter); HeapFree(GetProcessHeap(), 0, avimux); *phr = hr;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/filesource.c | 112 ++++++++++++++++----------------- dlls/quartz/tests/filesource.c | 6 -- 2 files changed, 55 insertions(+), 63 deletions(-)
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c index 34601da6b47..25bffe6c36c 100644 --- a/dlls/quartz/filesource.c +++ b/dlls/quartz/filesource.c @@ -50,6 +50,37 @@ static const AM_MEDIA_TYPE default_mt = NULL };
+typedef struct DATAREQUEST +{ + IMediaSample *pSample; + DWORD_PTR dwUserData; + OVERLAPPED ovl; +} DATAREQUEST; + +typedef struct FileAsyncReader +{ + BaseOutputPin pin; + IAsyncReader IAsyncReader_iface; + + ALLOCATOR_PROPERTIES allocProps; + HANDLE hFile; + BOOL bFlushing; + /* Why would you need more? Every sample has its own handle */ + LONG queued_number; + LONG samples; + LONG oldest_sample; + CRITICAL_SECTION csList; + DATAREQUEST *sample_list; + + /* Have a handle for every sample, and then one more as flushing handle */ + HANDLE *handle_list; +} FileAsyncReader; + +static inline FileAsyncReader *impl_from_IPin(IPin *iface) +{ + return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin.IPin_iface); +} + typedef struct AsyncReader { BaseFilter filter; @@ -407,14 +438,28 @@ static void async_reader_destroy(BaseFilter *iface)
if (filter->pOutputPin) { + FileAsyncReader *pin = impl_from_IPin(filter->pOutputPin); + unsigned int i; IPin *peer; + if (SUCCEEDED(IPin_ConnectedTo(filter->pOutputPin, &peer))) { IPin_Disconnect(peer); IPin_Release(peer); } IPin_Disconnect(filter->pOutputPin); - IPin_Release(filter->pOutputPin); + + CoTaskMemFree(pin->sample_list); + if (pin->handle_list) + { + for (i = 0; i <= pin->samples; ++i) + CloseHandle(pin->handle_list[i]); + CoTaskMemFree(pin->handle_list); + } + CloseHandle(pin->hFile); + pin->csList.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&pin->csList); + BaseOutputPin_Destroy(&pin->pin); } CoTaskMemFree(filter->pszFileName); if (filter->pmt) @@ -658,39 +703,6 @@ static const IFileSourceFilterVtbl FileSource_Vtbl = FileSource_GetCurFile };
- -/* the dwUserData passed back to user */ -typedef struct DATAREQUEST -{ - IMediaSample * pSample; /* sample passed to us by user */ - DWORD_PTR dwUserData; /* user data passed to us */ - OVERLAPPED ovl; /* our overlapped structure */ -} DATAREQUEST; - -typedef struct FileAsyncReader -{ - BaseOutputPin pin; - IAsyncReader IAsyncReader_iface; - - ALLOCATOR_PROPERTIES allocProps; - HANDLE hFile; - BOOL bFlushing; - /* Why would you need more? Every sample has its own handle */ - LONG queued_number; - LONG samples; - LONG oldest_sample; - CRITICAL_SECTION csList; /* critical section to prevent concurrency issues */ - DATAREQUEST *sample_list; - - /* Have a handle for every sample, and then one more as flushing handle */ - HANDLE *handle_list; -} FileAsyncReader; - -static inline FileAsyncReader *impl_from_IPin(IPin *iface) -{ - return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin.IPin_iface); -} - static inline FileAsyncReader *impl_from_BasePin(BasePin *iface) { return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin); @@ -765,36 +777,22 @@ static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID rii return E_NOINTERFACE; }
-static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface) +static ULONG WINAPI FileAsyncReaderPin_AddRef(IPin *iface) { - FileAsyncReader *This = impl_from_IPin(iface); - ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount); - int x; - - TRACE("(%p)->() Release from %d\n", This, refCount + 1); + FileAsyncReader *pin = impl_from_IPin(iface); + return IBaseFilter_AddRef(pin->pin.pin.pinInfo.pFilter); +}
- if (!refCount) - { - CoTaskMemFree(This->sample_list); - if (This->handle_list) - { - for (x = 0; x <= This->samples; ++x) - CloseHandle(This->handle_list[x]); - CoTaskMemFree(This->handle_list); - } - CloseHandle(This->hFile); - This->csList.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csList); - BaseOutputPin_Destroy(&This->pin); - return 0; - } - return refCount; +static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface) +{ + FileAsyncReader *pin = impl_from_IPin(iface); + return IBaseFilter_Release(pin->pin.pin.pinInfo.pFilter); }
static const IPinVtbl FileAsyncReaderPin_Vtbl = { FileAsyncReaderPin_QueryInterface, - BasePinImpl_AddRef, + FileAsyncReaderPin_AddRef, FileAsyncReaderPin_Release, BaseOutputPinImpl_Connect, BaseOutputPinImpl_ReceiveConnection, diff --git a/dlls/quartz/tests/filesource.c b/dlls/quartz/tests/filesource.c index 0bac51d799d..b1a8399d6e9 100644 --- a/dlls/quartz/tests/filesource.c +++ b/dlls/quartz/tests/filesource.c @@ -539,10 +539,8 @@ todo_wine hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -624,7 +622,6 @@ static void test_find_pin(void) hr = IBaseFilter_FindPin(filter, source_id, &pin); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 2, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); ok(ref == 2, "Got unexpected refcount %d.\n", ref); @@ -662,7 +659,6 @@ static void test_pin_info(void) hr = IBaseFilter_FindPin(filter, source_id, &pin); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 2, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); ok(ref == 2, "Got unexpected refcount %d.\n", ref); @@ -673,10 +669,8 @@ todo_wine ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir); ok(!lstrcmpW(info.achName, source_id), "Got name %s.\n", wine_dbgstr_w(info.achName)); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); IBaseFilter_Release(info.pFilter);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/parser.c | 13 ++------- dlls/quartz/pin.c | 48 ++++++++++++++++++---------------- dlls/quartz/pin.h | 4 ++- dlls/quartz/tests/avisplit.c | 3 --- dlls/quartz/tests/mpegsplit.c | 4 +-- dlls/quartz/tests/waveparser.c | 3 --- 6 files changed, 31 insertions(+), 44 deletions(-)
diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index 2666eb75aad..7e705ccb7f5 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -155,7 +155,6 @@ ULONG WINAPI Parser_AddRef(IBaseFilter * iface) void Parser_Destroy(ParserImpl *This) { IPin *connected = NULL; - ULONG pinref; HRESULT hr;
PullPin_WaitForStateChange(This->pInputPin, INFINITE); @@ -170,16 +169,8 @@ void Parser_Destroy(ParserImpl *This) hr = IPin_Disconnect(&This->pInputPin->pin.IPin_iface); assert(hr == S_OK); } - pinref = IPin_Release(&This->pInputPin->pin.IPin_iface); - if (pinref) - { - /* Valgrind could find this, if I kill it here */ - ERR("pinref should be null, is %u, destroying anyway\n", pinref); - assert((LONG)pinref > 0);
- while (pinref) - pinref = IPin_Release(&This->pInputPin->pin.IPin_iface); - } + PullPin_destroy(This->pInputPin);
CoTaskMemFree(This->ppPins); strmbase_filter_cleanup(&This->filter); @@ -734,7 +725,7 @@ static HRESULT WINAPI Parser_PullPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes static const IPinVtbl Parser_InputPin_Vtbl = { Parser_PullPin_QueryInterface, - BasePinImpl_AddRef, + PullPin_AddRef, PullPin_Release, BaseInputPinImpl_Connect, Parser_PullPin_ReceiveConnection, diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c index a3674f21ec0..5c1fcdcb6f3 100644 --- a/dlls/quartz/pin.c +++ b/dlls/quartz/pin.c @@ -364,32 +364,34 @@ HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) return E_NOINTERFACE; }
-ULONG WINAPI PullPin_Release(IPin *iface) +void PullPin_destroy(PullPin *pin) { - PullPin *This = impl_PullPin_from_IPin(iface); - ULONG refCount = InterlockedDecrement(&This->pin.refCount); - - TRACE("(%p)->() Release from %d\n", This, refCount + 1); + WaitForSingleObject(pin->hEventStateChanged, INFINITE); + assert(!pin->hThread); + + if (pin->prefAlloc) + IMemAllocator_Release(pin->prefAlloc); + if (pin->pAlloc) + IMemAllocator_Release(pin->pAlloc); + if (pin->pReader) + IAsyncReader_Release(pin->pReader); + CloseHandle(pin->thread_sleepy); + CloseHandle(pin->hEventStateChanged); + pin->thread_lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&pin->thread_lock); + CoTaskMemFree(pin); +}
- if (!refCount) - { - WaitForSingleObject(This->hEventStateChanged, INFINITE); - assert(!This->hThread); +ULONG WINAPI PullPin_AddRef(IPin *iface) +{ + PullPin *pin = impl_PullPin_from_IPin(iface); + return IBaseFilter_AddRef(pin->pin.pinInfo.pFilter); +}
- if(This->prefAlloc) - IMemAllocator_Release(This->prefAlloc); - if(This->pAlloc) - IMemAllocator_Release(This->pAlloc); - if(This->pReader) - IAsyncReader_Release(This->pReader); - CloseHandle(This->thread_sleepy); - CloseHandle(This->hEventStateChanged); - This->thread_lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->thread_lock); - CoTaskMemFree(This); - return 0; - } - return refCount; +ULONG WINAPI PullPin_Release(IPin *iface) +{ + PullPin *pin = impl_PullPin_from_IPin(iface); + return IBaseFilter_Release(pin->pin.pinInfo.pFilter); }
static void PullPin_Flush(PullPin *This) diff --git a/dlls/quartz/pin.h b/dlls/quartz/pin.h index 2f29c929cfb..b65d2239fb8 100644 --- a/dlls/quartz/pin.h +++ b/dlls/quartz/pin.h @@ -106,6 +106,7 @@ HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInf SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); +void PullPin_destroy(PullPin *pin) DECLSPEC_HIDDEN;
/**************************/ /*** Pin Implementation ***/ @@ -114,7 +115,8 @@ HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInf HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); HRESULT WINAPI PullPin_Disconnect(IPin * iface); HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); -ULONG WINAPI PullPin_Release(IPin * iface); +ULONG WINAPI PullPin_AddRef(IPin *iface) DECLSPEC_HIDDEN; +ULONG WINAPI PullPin_Release(IPin *iface) DECLSPEC_HIDDEN; HRESULT WINAPI PullPin_EndOfStream(IPin * iface); HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); HRESULT WINAPI PullPin_BeginFlush(IPin * iface); diff --git a/dlls/quartz/tests/avisplit.c b/dlls/quartz/tests/avisplit.c index 59edb387cbe..fb4278329b6 100644 --- a/dlls/quartz/tests/avisplit.c +++ b/dlls/quartz/tests/avisplit.c @@ -296,10 +296,8 @@ static void test_enum_pins(void) hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -487,7 +485,6 @@ static void test_pin_info(void) ref = get_refcount(filter); ok(ref == expect_ref + 1, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); -todo_wine ok(ref == expect_ref + 1, "Got unexpected refcount %d.\n", ref); IBaseFilter_Release(info.pFilter);
diff --git a/dlls/quartz/tests/mpegsplit.c b/dlls/quartz/tests/mpegsplit.c index c82c5b62767..9853a199083 100644 --- a/dlls/quartz/tests/mpegsplit.c +++ b/dlls/quartz/tests/mpegsplit.c @@ -293,10 +293,8 @@ static void test_enum_pins(void) hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -480,7 +478,7 @@ static void test_pin_info(void) ref = get_refcount(filter); ok(ref == expect_ref + 1, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); - todo_wine ok(ref == expect_ref + 1, "Got unexpected refcount %d.\n", ref); + ok(ref == expect_ref + 1, "Got unexpected refcount %d.\n", ref); IBaseFilter_Release(info.pFilter);
hr = IPin_QueryDirection(pin, &dir); diff --git a/dlls/quartz/tests/waveparser.c b/dlls/quartz/tests/waveparser.c index fd65099d972..84288c41df5 100644 --- a/dlls/quartz/tests/waveparser.c +++ b/dlls/quartz/tests/waveparser.c @@ -293,10 +293,8 @@ static void test_enum_pins(void) hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -480,7 +478,6 @@ static void test_pin_info(void) ref = get_refcount(filter); ok(ref == expect_ref + 1, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); -todo_wine ok(ref == expect_ref + 1, "Got unexpected refcount %d.\n", ref); IBaseFilter_Release(info.pFilter);
Uniquely, native quartz doesn't do this. But it doesn't make much sense to follow native quartz in this case, and it leads to simpler code on our part.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/parser.c | 49 +++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 30 deletions(-)
diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index 7e705ccb7f5..5743a53fd2e 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -383,26 +383,27 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR return hr; }
-static HRESULT WINAPI break_connection(IPin *iface) +static void free_source_pin(IPin *iface) { Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(iface); - HRESULT hr;
- if (!pin->pin.pin.pConnectedTo || !pin->pin.pMemInputPin) - hr = VFW_E_NOT_CONNECTED; - else + if (pin->pin.pin.pConnectedTo) { - hr = IPin_Disconnect(pin->pin.pin.pConnectedTo); + IPin_Disconnect(pin->pin.pin.pConnectedTo); IPin_Disconnect(iface); }
- return hr; + FreeMediaType(pin->pmt); + CoTaskMemFree(pin->pmt); + FreeMediaType(&pin->pin.pin.mtCurrent); + if (pin->pin.pAllocator) + IMemAllocator_Release(pin->pin.pAllocator); + CoTaskMemFree(pin); }
static HRESULT Parser_RemoveOutputPins(ParserImpl * This) { /* NOTE: should be in critical section when calling this function */ - HRESULT hr; ULONG i; IPin ** ppOldPins = This->ppPins;
@@ -413,11 +414,7 @@ static HRESULT Parser_RemoveOutputPins(ParserImpl * This) memcpy(This->ppPins, ppOldPins, sizeof(IPin *) * 1);
for (i = 0; i < This->cStreams; i++) - { - hr = break_connection(ppOldPins[i + 1]); - TRACE("Disconnect: %08x\n", hr); - IPin_Release(ppOldPins[i + 1]); - } + free_source_pin(ppOldPins[i + 1]);
BaseFilterImpl_IncrementPinVersion(&This->filter); This->cStreams = 0; @@ -567,24 +564,16 @@ static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, return E_NOINTERFACE; }
-static ULONG WINAPI Parser_OutputPin_Release(IPin * iface) +static ULONG WINAPI Parser_OutputPin_AddRef(IPin *iface) { - Parser_OutputPin *This = unsafe_impl_Parser_OutputPin_from_IPin(iface); - ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount); - - TRACE("(%p)->() Release from %d\n", iface, refCount + 1); + Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(iface); + return IBaseFilter_AddRef(pin->pin.pin.pinInfo.pFilter); +}
- if (!refCount) - { - FreeMediaType(This->pmt); - CoTaskMemFree(This->pmt); - FreeMediaType(&This->pin.pin.mtCurrent); - if (This->pin.pAllocator) - IMemAllocator_Release(This->pin.pAllocator); - CoTaskMemFree(This); - return 0; - } - return refCount; +static ULONG WINAPI Parser_OutputPin_Release(IPin * iface) +{ + Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(iface); + return IBaseFilter_Release(pin->pin.pin.pinInfo.pFilter); }
static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) @@ -612,7 +601,7 @@ static HRESULT WINAPI Parser_OutputPin_CheckMediaType(BasePin *pin, const AM_MED static const IPinVtbl Parser_OutputPin_Vtbl = { Parser_OutputPin_QueryInterface, - BasePinImpl_AddRef, + Parser_OutputPin_AddRef, Parser_OutputPin_Release, Parser_OutputPin_Connect, BaseOutputPinImpl_ReceiveConnection,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/acmwrapper.c | 10 +++------- dlls/quartz/tests/avidec.c | 10 +++------- dlls/strmbase/transform.c | 36 ++++++++++++++++++++++++++++------ 3 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/dlls/quartz/tests/acmwrapper.c b/dlls/quartz/tests/acmwrapper.c index 1c418723df7..1f07e507830 100644 --- a/dlls/quartz/tests/acmwrapper.c +++ b/dlls/quartz/tests/acmwrapper.c @@ -229,10 +229,8 @@ static void test_enum_pins(void) hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -243,10 +241,8 @@ todo_wine hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -383,7 +379,7 @@ static void test_pin_info(void) hr = IBaseFilter_FindPin(filter, sink_id, &pin); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); - todo_wine ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); ok(ref == 2, "Got unexpected refcount %d.\n", ref);
@@ -394,9 +390,9 @@ static void test_pin_info(void) todo_wine ok(!lstrcmpW(info.achName, sink_name), "Got name %s.\n", wine_dbgstr_w(info.achName)); ref = get_refcount(filter); - todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); - todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ok(ref == 3, "Got unexpected refcount %d.\n", ref); IBaseFilter_Release(info.pFilter);
hr = IPin_QueryDirection(pin, &dir); diff --git a/dlls/quartz/tests/avidec.c b/dlls/quartz/tests/avidec.c index 0183e0bea80..3f92876c84c 100644 --- a/dlls/quartz/tests/avidec.c +++ b/dlls/quartz/tests/avidec.c @@ -254,10 +254,8 @@ static void test_enum_pins(void) hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -268,10 +266,8 @@ todo_wine hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pins[0]); -todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); @@ -408,7 +404,7 @@ static void test_pin_info(void) hr = IBaseFilter_FindPin(filter, sink_id, &pin); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); - todo_wine ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); ok(ref == 2, "Got unexpected refcount %d.\n", ref);
@@ -418,9 +414,9 @@ static void test_pin_info(void) ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir); todo_wine ok(!lstrcmpW(info.achName, sink_name), "Got name %s.\n", wine_dbgstr_w(info.achName)); ref = get_refcount(filter); - todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); - todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ok(ref == 3, "Got unexpected refcount %d.\n", ref); IBaseFilter_Release(info.pFilter);
hr = IPin_QueryDirection(pin, &dir); diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c index fe54ebe861f..4c32d673253 100644 --- a/dlls/strmbase/transform.c +++ b/dlls/strmbase/transform.c @@ -153,9 +153,11 @@ static void transform_destroy(BaseFilter *iface) IPin_Release(peer); } IPin_Disconnect(filter->ppPins[i]); - IPin_Release(filter->ppPins[i]); }
+ BaseInputPin_Destroy(impl_BaseInputPin_from_IPin(filter->ppPins[0])); + BaseOutputPin_Destroy(impl_BaseOutputPin_from_IPin(filter->ppPins[1])); + CoTaskMemFree(filter->ppPins);
filter->csReceive.DebugInfo->Spare[0] = 0; @@ -379,7 +381,17 @@ HRESULT WINAPI TransformFilterImpl_Notify(TransformFilter *iface, IBaseFilter *s return QualityControlImpl_Notify((IQualityControl*)iface->qcimpl, sender, qm); }
-/** IBaseFilter implementation **/ +static ULONG WINAPI TransformFilter_InputPin_AddRef(IPin *iface) +{ + BaseInputPin *pin = impl_BaseInputPin_from_IPin(iface); + return IBaseFilter_AddRef(pin->pin.pinInfo.pFilter); +} + +static ULONG WINAPI TransformFilter_InputPin_Release(IPin *iface) +{ + BaseInputPin *pin = impl_BaseInputPin_from_IPin(iface); + return IBaseFilter_Release(pin->pin.pinInfo.pFilter); +}
static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface) { @@ -504,8 +516,8 @@ static HRESULT WINAPI TransformFilter_InputPin_NewSegment(IPin * iface, REFERENC static const IPinVtbl TransformFilter_InputPin_Vtbl = { BaseInputPinImpl_QueryInterface, - BasePinImpl_AddRef, - BaseInputPinImpl_Release, + TransformFilter_InputPin_AddRef, + TransformFilter_InputPin_Release, BaseInputPinImpl_Connect, TransformFilter_InputPin_ReceiveConnection, TransformFilter_InputPin_Disconnect, @@ -543,11 +555,23 @@ static HRESULT WINAPI transform_source_QueryInterface(IPin *iface, REFIID iid, v return S_OK; }
+static ULONG WINAPI transform_source_AddRef(IPin *iface) +{ + BaseOutputPin *pin = impl_BaseOutputPin_from_IPin(iface); + return IBaseFilter_AddRef(pin->pin.pinInfo.pFilter); +} + +static ULONG WINAPI transform_source_Release(IPin *iface) +{ + BaseOutputPin *pin = impl_BaseOutputPin_from_IPin(iface); + return IBaseFilter_Release(pin->pin.pinInfo.pFilter); +} + static const IPinVtbl TransformFilter_OutputPin_Vtbl = { transform_source_QueryInterface, - BasePinImpl_AddRef, - BaseOutputPinImpl_Release, + transform_source_AddRef, + transform_source_Release, BaseOutputPinImpl_Connect, BaseOutputPinImpl_ReceiveConnection, BaseOutputPinImpl_Disconnect,