Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
7dea79c4
Commit
7dea79c4
authored
Mar 02, 2005
by
Christian Costa
Committed by
Alexandre Julliard
Mar 02, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle End Of Stream notifications.
Some AVI Splitter fixes.
parent
46ebd667
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
162 additions
and
24 deletions
+162
-24
avisplit.c
dlls/quartz/avisplit.c
+52
-11
dsoundrender.c
dlls/quartz/dsoundrender.c
+12
-7
filtergraph.c
dlls/quartz/filtergraph.c
+7
-2
pin.c
dlls/quartz/pin.c
+1
-1
filtergraph.c
dlls/quartz/tests/filtergraph.c
+12
-0
transform.c
dlls/quartz/transform.c
+27
-1
videorenderer.c
dlls/quartz/videorenderer.c
+20
-1
waveparser.c
dlls/quartz/waveparser.c
+31
-1
No files found.
dlls/quartz/avisplit.c
View file @
7dea79c4
...
...
@@ -55,11 +55,14 @@ typedef struct AVISplitterImpl
AVIMAINHEADER
AviHeader
;
}
AVISplitterImpl
;
static
HRESULT
AVISplitter_NextChunk
(
LONGLONG
*
pllCurrentChunkOffset
,
RIFFCHUNK
*
pCurrentChunk
,
const
REFERENCE_TIME
*
tStart
,
const
REFERENCE_TIME
*
tStop
,
const
BYTE
*
pbSrcStream
)
static
HRESULT
AVISplitter_NextChunk
(
LONGLONG
*
pllCurrentChunkOffset
,
RIFFCHUNK
*
pCurrentChunk
,
const
REFERENCE_TIME
*
tStart
,
const
REFERENCE_TIME
*
tStop
,
const
BYTE
*
pbSrcStream
,
int
inner
)
{
if
(
inner
)
*
pllCurrentChunkOffset
+=
MEDIATIME_FROM_BYTES
(
sizeof
(
RIFFLIST
));
else
*
pllCurrentChunkOffset
+=
MEDIATIME_FROM_BYTES
(
sizeof
(
RIFFCHUNK
)
+
RIFFROUND
(
pCurrentChunk
->
cb
));
if
(
*
pllCurrentChunkOffset
>
*
tStop
)
if
(
*
pllCurrentChunkOffset
>
=
*
tStop
)
return
S_FALSE
;
/* no more data - we couldn't even get the next chunk header! */
else
if
(
*
pllCurrentChunkOffset
+
MEDIATIME_FROM_BYTES
(
sizeof
(
RIFFCHUNK
))
>=
*
tStop
)
{
...
...
@@ -88,7 +91,7 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
cbSrcStream
=
IMediaSample_GetActualDataLength
(
pSample
);
/* trace removed for performance reasons */
/*
TRACE("(%p)\n", pSample); */
/*
TRACE("(%p)\n", pSample); */
assert
(
BYTES_FROM_MEDIATIME
(
tStop
-
tStart
)
==
cbSrcStream
);
...
...
@@ -104,7 +107,8 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
if
(
offset
>=
(
DWORD
)
cbSrcStream
)
{
FIXME
(
"large offset
\n
"
);
return
S_OK
;
hr
=
S_OK
;
goto
skip
;
}
memcpy
(
&
This
->
CurrentChunk
,
pbSrcStream
+
offset
,
sizeof
(
RIFFCHUNK
));
...
...
@@ -132,7 +136,7 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
case
ckidJUNK
:
case
aviFCC
(
'i'
,
'd'
,
'x'
,
'1'
):
/* Index is not handled */
/* silently ignore */
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
))
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
,
FALSE
))
bMoreData
=
FALSE
;
continue
;
case
ckidLIST
:
...
...
@@ -141,12 +145,16 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
{
/* FIXME: We only advanced to the first chunk inside the list without keeping track that we are in it.
* This is not clean and the parser should be improved for that but it is enough for most AVI files. */
This
->
CurrentChunkOffset
=
MEDIATIME_FROM_BYTES
(
BYTES_FROM_MEDIATIME
(
This
->
CurrentChunkOffset
)
+
sizeof
(
RIFFLIST
));
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
,
TRUE
))
{
bMoreData
=
FALSE
;
continue
;
}
This
->
CurrentChunk
=
*
(
RIFFCHUNK
*
)
(
pbSrcStream
+
BYTES_FROM_MEDIATIME
(
This
->
CurrentChunkOffset
-
tStart
));
offset_src
=
(
long
)
BYTES_FROM_MEDIATIME
(
This
->
CurrentChunkOffset
-
tStart
)
+
sizeof
(
RIFFCHUNK
);
break
;
}
else
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
))
else
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
,
FALSE
))
bMoreData
=
FALSE
;
continue
;
default:
...
...
@@ -168,7 +176,7 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
break;
default:
FIXME("Skipping unknown chunk type: %s at file offset 0x%lx\n", debugstr_an((LPSTR)&This->CurrentChunk.fcc, 4), (DWORD)BYTES_FROM_MEDIATIME(This->CurrentChunkOffset));
if (S_FALSE == AVISplitter_NextChunk(&This->CurrentChunkOffset, &This->CurrentChunk, &tStart, &tStop, pbSrcStream))
if (S_FALSE == AVISplitter_NextChunk(&This->CurrentChunkOffset, &This->CurrentChunk, &tStart, &tStop, pbSrcStream
, FALSE
))
bMoreData = FALSE;
continue;
}
...
...
@@ -180,7 +188,8 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
if
(
streamId
>
This
->
Parser
.
cStreams
)
{
ERR
(
"Corrupted AVI file (contains stream id %d, but supposed to only have %ld streams)
\n
"
,
streamId
,
This
->
Parser
.
cStreams
);
return
E_FAIL
;
hr
=
E_FAIL
;
break
;
}
pOutputPin
=
(
Parser_OutputPin
*
)
This
->
Parser
.
ppPins
[
streamId
+
1
];
...
...
@@ -200,7 +209,7 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
{
TRACE
(
"Skipping sending sample for stream %02d due to error (%lx)
\n
"
,
streamId
,
hr
);
This
->
pCurrentSample
=
NULL
;
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
))
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
,
FALSE
))
bMoreData
=
FALSE
;
continue
;
}
...
...
@@ -263,7 +272,7 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
This
->
pCurrentSample
=
NULL
;
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
))
if
(
S_FALSE
==
AVISplitter_NextChunk
(
&
This
->
CurrentChunkOffset
,
&
This
->
CurrentChunk
,
&
tStart
,
&
tStop
,
pbSrcStream
,
FALSE
))
bMoreData
=
FALSE
;
}
else
...
...
@@ -276,6 +285,38 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample)
bMoreData
=
FALSE
;
}
}
skip:
if
(
tStop
>=
This
->
EndOfFile
)
{
int
i
;
TRACE
(
"End of file reached
\n
"
);
for
(
i
=
0
;
i
<
This
->
Parser
.
cStreams
;
i
++
)
{
IPin
*
ppin
;
HRESULT
hr
;
TRACE
(
"Send End Of Stream to output pin %d
\n
"
,
i
);
hr
=
IPin_ConnectedTo
(
This
->
Parser
.
ppPins
[
i
+
1
],
&
ppin
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IPin_EndOfStream
(
ppin
);
IPin_Release
(
ppin
);
}
if
(
FAILED
(
hr
))
{
ERR
(
"%lx
\n
"
,
hr
);
break
;
}
}
/* Force the pullpin thread to stop */
hr
=
S_FALSE
;
}
return
hr
;
}
...
...
dlls/quartz/dsoundrender.c
View file @
7dea79c4
...
...
@@ -58,7 +58,6 @@ typedef struct DSoundRenderImpl
REFERENCE_TIME
rtStreamStart
;
IReferenceClock
*
pClock
;
FILTER_INFO
filterInfo
;
IMediaEventSink
*
pEventSink
;
InputPin
*
pInputPin
;
IPin
**
ppPins
;
...
...
@@ -550,7 +549,6 @@ static HRESULT WINAPI DSoundRender_QueryFilterInfo(IBaseFilter * iface, FILTER_I
static
HRESULT
WINAPI
DSoundRender_JoinFilterGraph
(
IBaseFilter
*
iface
,
IFilterGraph
*
pGraph
,
LPCWSTR
pName
)
{
HRESULT
hr
;
DSoundRenderImpl
*
This
=
(
DSoundRenderImpl
*
)
iface
;
TRACE
(
"(%p/%p)->(%p, %s)
\n
"
,
This
,
iface
,
pGraph
,
debugstr_w
(
pName
));
...
...
@@ -562,12 +560,10 @@ static HRESULT WINAPI DSoundRender_JoinFilterGraph(IBaseFilter * iface, IFilterG
else
*
This
->
filterInfo
.
achName
=
'\0'
;
This
->
filterInfo
.
pGraph
=
pGraph
;
/* NOTE: do NOT increase ref. count */
hr
=
IFilterGraph_QueryInterface
(
pGraph
,
&
IID_IMediaEventSink
,
(
LPVOID
*
)
&
This
->
pEventSink
);
}
LeaveCriticalSection
(
&
This
->
csFilter
);
return
hr
;
return
S_OK
;
}
static
HRESULT
WINAPI
DSoundRender_QueryVendorInfo
(
IBaseFilter
*
iface
,
LPWSTR
*
pVendorInfo
)
...
...
@@ -598,12 +594,21 @@ static const IBaseFilterVtbl DSoundRender_Vtbl =
static
HRESULT
WINAPI
DSoundRender_InputPin_EndOfStream
(
IPin
*
iface
)
{
/* FIXME: critical section */
InputPin
*
This
=
(
InputPin
*
)
iface
;
IMediaEventSink
*
pEventSink
;
HRESULT
hr
;
TRACE
(
"(%p/%p)->()
\n
"
,
This
,
iface
);
return
IMediaEventSink_Notify
(((
DSoundRenderImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
)
->
pEventSink
,
EC_COMPLETE
,
S_OK
,
0
);
hr
=
IFilterGraph_QueryInterface
(((
DSoundRenderImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
)
->
filterInfo
.
pGraph
,
&
IID_IMediaEventSink
,
(
LPVOID
*
)
&
pEventSink
);
if
(
SUCCEEDED
(
hr
))
{
/* FIXME: We should wait that all audio data has been played */
hr
=
IMediaEventSink_Notify
(
pEventSink
,
EC_COMPLETE
,
S_OK
,
0
);
IMediaEventSink_Release
(
pEventSink
);
}
return
hr
;
}
static
const
IPinVtbl
DSoundRender_InputPin_Vtbl
=
...
...
dlls/quartz/filtergraph.c
View file @
7dea79c4
...
...
@@ -2995,14 +2995,19 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, long EventCo
if
((
EventCode
==
EC_COMPLETE
)
&&
This
->
HandleEcComplete
)
{
TRACE
(
"Process EC_COMPLETE notification
\n
"
);
if
(
++
This
->
EcCompleteCount
==
This
->
nRenderers
)
{
evt
.
lEventCode
=
EC_COMPLETE
;
evt
.
lParam1
=
S_OK
;
evt
.
lParam2
=
0
;
TRACE
(
"Send EC_COMPLETE to app
\n
"
);
EventsQueue_PutEvent
(
&
This
->
evqueue
,
&
evt
);
if
(
!
This
->
notif
.
disabled
&&
This
->
notif
.
hWnd
)
{
TRACE
(
"Send Window message
\n
"
);
PostMessageW
(
This
->
notif
.
hWnd
,
This
->
notif
.
msg
,
0
,
This
->
notif
.
instance
);
}
This
->
CompletionStatus
=
EC_COMPLETE
;
SetEvent
(
This
->
hEventCompletion
);
}
...
...
@@ -3059,11 +3064,11 @@ HRESULT FILTERGRAPH_create(IUnknown *pUnkOuter, LPVOID *ppObj) {
fimpl
->
nFilters
=
0
;
fimpl
->
filterCapacity
=
0
;
fimpl
->
nameIndex
=
1
;
fimpl
->
hEventCompletion
=
CreateEventW
(
0
,
TRUE
,
FALSE
,
0
);
fimpl
->
hEventCompletion
=
CreateEventW
(
0
,
TRUE
,
FALSE
,
0
);
fimpl
->
HandleEcComplete
=
TRUE
;
fimpl
->
HandleEcRepaint
=
TRUE
;
fimpl
->
notif
.
hWnd
=
0
;
fimpl
->
notif
.
disabled
=
TRU
E
;
fimpl
->
notif
.
disabled
=
FALS
E
;
fimpl
->
nRenderers
=
0
;
fimpl
->
EcCompleteCount
=
0
;
fimpl
->
state
=
State_Stopped
;
...
...
dlls/quartz/pin.c
View file @
7dea79c4
...
...
@@ -1158,7 +1158,7 @@ static void CALLBACK PullPin_Thread_Process(ULONG_PTR iface)
TRACE
(
"Start
\n
"
);
while
(
rtCurrent
<
This
->
rtStop
)
while
(
rtCurrent
<
This
->
rtStop
&&
hr
==
S_OK
)
{
/* FIXME: to improve performance by quite a bit this should be changed
* so that one sample is processed while one sample is fetched. However,
...
...
dlls/quartz/tests/filtergraph.c
View file @
7dea79c4
...
...
@@ -51,6 +51,8 @@ static void rungraph()
{
HRESULT
hr
;
IMediaControl
*
pmc
;
IMediaEvent
*
pme
;
HANDLE
hEvent
;
hr
=
IGraphBuilder_QueryInterface
(
pgraph
,
&
IID_IMediaControl
,
(
LPVOID
*
)
&
pmc
);
ok
(
hr
==
S_OK
,
"Cannot get IMediaControl interface returned: %lx
\n
"
,
hr
);
...
...
@@ -58,8 +60,18 @@ static void rungraph()
hr
=
IMediaControl_Run
(
pmc
);
ok
(
hr
==
S_FALSE
,
"Cannot run the graph returned: %lx
\n
"
,
hr
);
hr
=
IGraphBuilder_QueryInterface
(
pgraph
,
&
IID_IMediaEvent
,
(
LPVOID
*
)
&
pme
);
ok
(
hr
==
S_OK
,
"Cannot get IMediaEvent interface returned: %lx
\n
"
,
hr
);
hr
=
IMediaEvent_GetEventHandle
(
pme
,
(
OAEVENT
*
)
&
hEvent
);
ok
(
hr
==
S_OK
,
"Cannot get event handle returned: %lx
\n
"
,
hr
);
/* WaitForSingleObject(hEvent, INFINITE); */
Sleep
(
20000
);
hr
=
IMediaControl_Release
(
pme
);
ok
(
hr
==
2
,
"Releasing mediaevent returned: %lx
\n
"
,
hr
);
hr
=
IMediaControl_Stop
(
pmc
);
ok
(
hr
==
S_OK
,
"Cannot stop the graph returned: %lx
\n
"
,
hr
);
...
...
dlls/quartz/transform.c
View file @
7dea79c4
...
...
@@ -495,6 +495,32 @@ static const IBaseFilterVtbl TransformFilter_Vtbl =
TransformFilter_QueryVendorInfo
};
HRESULT
WINAPI
TransformFilter_InputPin_EndOfStream
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
TransformFilterImpl
*
pTransform
;
IPin
*
ppin
;
HRESULT
hr
;
TRACE
(
"(%p)->()
\n
"
,
iface
);
/* Since we process samples synchronously, just forward notification downstream */
pTransform
=
(
TransformFilterImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
if
(
!
pTransform
)
hr
=
E_FAIL
;
else
hr
=
IPin_ConnectedTo
(
pTransform
->
ppPins
[
1
],
&
ppin
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IPin_EndOfStream
(
ppin
);
IPin_Release
(
ppin
);
}
if
(
FAILED
(
hr
))
ERR
(
"%lx
\n
"
,
hr
);
return
hr
;
}
static
const
IPinVtbl
TransformFilter_InputPin_Vtbl
=
{
InputPin_QueryInterface
,
...
...
@@ -511,7 +537,7 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
IPinImpl_QueryAccept
,
IPinImpl_EnumMediaTypes
,
IPinImpl_QueryInternalConnections
,
InputPin_EndOfStream
,
TransformFilter_
InputPin_EndOfStream
,
InputPin_BeginFlush
,
InputPin_EndFlush
,
InputPin_NewSegment
...
...
dlls/quartz/videorenderer.c
View file @
7dea79c4
...
...
@@ -34,6 +34,7 @@
#include "windef.h"
#include "winbase.h"
#include "dshow.h"
#include "evcode.h"
#include "strmif.h"
#include "ddraw.h"
...
...
@@ -635,6 +636,24 @@ static const IBaseFilterVtbl VideoRenderer_Vtbl =
VideoRenderer_QueryVendorInfo
};
static
HRESULT
WINAPI
VideoRenderer_InputPin_EndOfStream
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
IMediaEventSink
*
pEventSink
;
HRESULT
hr
;
TRACE
(
"(%p/%p)->()
\n
"
,
This
,
iface
);
hr
=
IFilterGraph_QueryInterface
(((
VideoRendererImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
)
->
filterInfo
.
pGraph
,
&
IID_IMediaEventSink
,
(
LPVOID
*
)
&
pEventSink
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IMediaEventSink_Notify
(
pEventSink
,
EC_COMPLETE
,
S_OK
,
0
);
IMediaEventSink_Release
(
pEventSink
);
}
return
hr
;
}
static
const
IPinVtbl
VideoRenderer_InputPin_Vtbl
=
{
InputPin_QueryInterface
,
...
...
@@ -651,7 +670,7 @@ static const IPinVtbl VideoRenderer_InputPin_Vtbl =
IPinImpl_QueryAccept
,
IPinImpl_EnumMediaTypes
,
IPinImpl_QueryInternalConnections
,
InputPin_EndOfStream
,
VideoRenderer_
InputPin_EndOfStream
,
InputPin_BeginFlush
,
InputPin_EndFlush
,
InputPin_NewSegment
...
...
dlls/quartz/waveparser.c
View file @
7dea79c4
...
...
@@ -97,7 +97,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample)
{
TRACE
(
"Skipping sending sample due to error (%lx)
\n
"
,
hr
);
This
->
pCurrentSample
=
NULL
;
return
hr
;
break
;
}
}
...
...
@@ -167,6 +167,36 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample)
offset_src
+=
chunk_remaining_bytes
;
}
if
(
tStop
>=
This
->
EndOfFile
)
{
int
i
;
TRACE
(
"End of file reached
\n
"
);
for
(
i
=
0
;
i
<
This
->
Parser
.
cStreams
;
i
++
)
{
IPin
*
ppin
;
HRESULT
hr
;
TRACE
(
"Send End Of Stream to output pin %d
\n
"
,
i
);
hr
=
IPin_ConnectedTo
(
This
->
Parser
.
ppPins
[
i
+
1
],
&
ppin
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IPin_EndOfStream
(
ppin
);
IPin_Release
(
ppin
);
}
if
(
FAILED
(
hr
))
{
ERR
(
"%lx
\n
"
,
hr
);
break
;
}
}
/* Force the pullpin thread to stop */
hr
=
S_FALSE
;
}
return
hr
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment