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
4ba31162
Commit
4ba31162
authored
Oct 04, 2021
by
Zebediah Figura
Committed by
Alexandre Julliard
Oct 05, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Convert the Unix library to the __wine_unix_call interface.
Signed-off-by:
Zebediah Figura
<
zfigura@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
494039d0
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
528 additions
and
167 deletions
+528
-167
Makefile.in
dlls/winegstreamer/Makefile.in
+1
-0
gst_private.h
dlls/winegstreamer/gst_private.h
+31
-1
main.c
dlls/winegstreamer/main.c
+195
-2
media_source.c
dlls/winegstreamer/media_source.c
+22
-22
quartz_parser.c
dlls/winegstreamer/quartz_parser.c
+36
-36
unixlib.h
dlls/winegstreamer/unixlib.h
+112
-27
wg_parser.c
dlls/winegstreamer/wg_parser.c
+131
-79
No files found.
dlls/winegstreamer/Makefile.in
View file @
4ba31162
MODULE
=
winegstreamer.dll
UNIXLIB
=
winegstreamer.so
IMPORTS
=
strmbase strmiids uuid ole32 mfuuid
DELAYIMPORTS
=
mfplat
EXTRAINCL
=
$(GSTREAMER_CFLAGS)
...
...
dlls/winegstreamer/gst_private.h
View file @
4ba31162
...
...
@@ -61,7 +61,37 @@ static inline const char *debugstr_time(REFERENCE_TIME time)
#define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
extern
const
struct
unix_funcs
*
unix_funcs
;
struct
wg_parser
*
wg_parser_create
(
enum
wg_parser_type
type
,
bool
unlimited_buffering
)
DECLSPEC_HIDDEN
;
void
wg_parser_destroy
(
struct
wg_parser
*
parser
)
DECLSPEC_HIDDEN
;
HRESULT
wg_parser_connect
(
struct
wg_parser
*
parser
,
uint64_t
file_size
)
DECLSPEC_HIDDEN
;
void
wg_parser_disconnect
(
struct
wg_parser
*
parser
)
DECLSPEC_HIDDEN
;
void
wg_parser_begin_flush
(
struct
wg_parser
*
parser
)
DECLSPEC_HIDDEN
;
void
wg_parser_end_flush
(
struct
wg_parser
*
parser
)
DECLSPEC_HIDDEN
;
bool
wg_parser_get_next_read_offset
(
struct
wg_parser
*
parser
,
uint64_t
*
offset
,
uint32_t
*
size
)
DECLSPEC_HIDDEN
;
void
wg_parser_push_data
(
struct
wg_parser
*
parser
,
const
void
*
data
,
uint32_t
size
)
DECLSPEC_HIDDEN
;
uint32_t
wg_parser_get_stream_count
(
struct
wg_parser
*
parser
)
DECLSPEC_HIDDEN
;
struct
wg_parser_stream
*
wg_parser_get_stream
(
struct
wg_parser
*
parser
,
uint32_t
index
)
DECLSPEC_HIDDEN
;
void
wg_parser_stream_get_preferred_format
(
struct
wg_parser_stream
*
stream
,
struct
wg_format
*
format
)
DECLSPEC_HIDDEN
;
void
wg_parser_stream_enable
(
struct
wg_parser_stream
*
stream
,
const
struct
wg_format
*
format
)
DECLSPEC_HIDDEN
;
void
wg_parser_stream_disable
(
struct
wg_parser_stream
*
stream
)
DECLSPEC_HIDDEN
;
bool
wg_parser_stream_get_event
(
struct
wg_parser_stream
*
stream
,
struct
wg_parser_event
*
event
)
DECLSPEC_HIDDEN
;
bool
wg_parser_stream_copy_buffer
(
struct
wg_parser_stream
*
stream
,
void
*
data
,
uint32_t
offset
,
uint32_t
size
)
DECLSPEC_HIDDEN
;
void
wg_parser_stream_release_buffer
(
struct
wg_parser_stream
*
stream
)
DECLSPEC_HIDDEN
;
void
wg_parser_stream_notify_qos
(
struct
wg_parser_stream
*
stream
,
bool
underflow
,
double
proportion
,
int64_t
diff
,
uint64_t
timestamp
)
DECLSPEC_HIDDEN
;
/* Returns the duration in 100-nanosecond units. */
uint64_t
wg_parser_stream_get_duration
(
struct
wg_parser_stream
*
stream
)
DECLSPEC_HIDDEN
;
/* start_pos and stop_pos are in 100-nanosecond units. */
void
wg_parser_stream_seek
(
struct
wg_parser_stream
*
stream
,
double
rate
,
uint64_t
start_pos
,
uint64_t
stop_pos
,
DWORD
start_flags
,
DWORD
stop_flags
)
DECLSPEC_HIDDEN
;
HRESULT
avi_splitter_create
(
IUnknown
*
outer
,
IUnknown
**
out
)
DECLSPEC_HIDDEN
;
HRESULT
decodebin_parser_create
(
IUnknown
*
outer
,
IUnknown
**
out
)
DECLSPEC_HIDDEN
;
...
...
dlls/winegstreamer/main.c
View file @
4ba31162
...
...
@@ -27,16 +27,209 @@
#include "initguid.h"
#include "gst_guids.h"
static
unixlib_handle_t
unix_handle
;
WINE_DEFAULT_DEBUG_CHANNEL
(
quartz
);
const
struct
unix_funcs
*
unix_funcs
=
NULL
;
struct
wg_parser
*
wg_parser_create
(
enum
wg_parser_type
type
,
bool
unlimited_buffering
)
{
struct
wg_parser_create_params
params
=
{
.
type
=
type
,
.
unlimited_buffering
=
unlimited_buffering
,
};
if
(
__wine_unix_call
(
unix_handle
,
unix_wg_parser_create
,
&
params
))
return
NULL
;
return
params
.
parser
;
}
void
wg_parser_destroy
(
struct
wg_parser
*
parser
)
{
__wine_unix_call
(
unix_handle
,
unix_wg_parser_destroy
,
parser
);
}
HRESULT
wg_parser_connect
(
struct
wg_parser
*
parser
,
uint64_t
file_size
)
{
struct
wg_parser_connect_params
params
=
{
.
parser
=
parser
,
.
file_size
=
file_size
,
};
return
__wine_unix_call
(
unix_handle
,
unix_wg_parser_connect
,
&
params
);
}
void
wg_parser_disconnect
(
struct
wg_parser
*
parser
)
{
__wine_unix_call
(
unix_handle
,
unix_wg_parser_disconnect
,
parser
);
}
void
wg_parser_begin_flush
(
struct
wg_parser
*
parser
)
{
__wine_unix_call
(
unix_handle
,
unix_wg_parser_begin_flush
,
parser
);
}
void
wg_parser_end_flush
(
struct
wg_parser
*
parser
)
{
__wine_unix_call
(
unix_handle
,
unix_wg_parser_end_flush
,
parser
);
}
bool
wg_parser_get_next_read_offset
(
struct
wg_parser
*
parser
,
uint64_t
*
offset
,
uint32_t
*
size
)
{
struct
wg_parser_get_next_read_offset_params
params
=
{
.
parser
=
parser
,
};
if
(
__wine_unix_call
(
unix_handle
,
unix_wg_parser_get_next_read_offset
,
&
params
))
return
false
;
*
offset
=
params
.
offset
;
*
size
=
params
.
size
;
return
true
;
}
void
wg_parser_push_data
(
struct
wg_parser
*
parser
,
const
void
*
data
,
uint32_t
size
)
{
struct
wg_parser_push_data_params
params
=
{
.
parser
=
parser
,
.
data
=
data
,
.
size
=
size
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_push_data
,
&
params
);
}
uint32_t
wg_parser_get_stream_count
(
struct
wg_parser
*
parser
)
{
struct
wg_parser_get_stream_count_params
params
=
{
.
parser
=
parser
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_get_stream_count
,
&
params
);
return
params
.
count
;
}
struct
wg_parser_stream
*
wg_parser_get_stream
(
struct
wg_parser
*
parser
,
uint32_t
index
)
{
struct
wg_parser_get_stream_params
params
=
{
.
parser
=
parser
,
.
index
=
index
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_get_stream
,
&
params
);
return
params
.
stream
;
}
void
wg_parser_stream_get_preferred_format
(
struct
wg_parser_stream
*
stream
,
struct
wg_format
*
format
)
{
struct
wg_parser_stream_get_preferred_format_params
params
=
{
.
stream
=
stream
,
.
format
=
format
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_get_preferred_format
,
&
params
);
}
void
wg_parser_stream_enable
(
struct
wg_parser_stream
*
stream
,
const
struct
wg_format
*
format
)
{
struct
wg_parser_stream_enable_params
params
=
{
.
stream
=
stream
,
.
format
=
format
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_enable
,
&
params
);
}
void
wg_parser_stream_disable
(
struct
wg_parser_stream
*
stream
)
{
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_disable
,
stream
);
}
bool
wg_parser_stream_get_event
(
struct
wg_parser_stream
*
stream
,
struct
wg_parser_event
*
event
)
{
struct
wg_parser_stream_get_event_params
params
=
{
.
stream
=
stream
,
.
event
=
event
,
};
return
!
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_get_event
,
&
params
);
}
bool
wg_parser_stream_copy_buffer
(
struct
wg_parser_stream
*
stream
,
void
*
data
,
uint32_t
offset
,
uint32_t
size
)
{
struct
wg_parser_stream_copy_buffer_params
params
=
{
.
stream
=
stream
,
.
data
=
data
,
.
offset
=
offset
,
.
size
=
size
,
};
return
!
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_copy_buffer
,
&
params
);
}
void
wg_parser_stream_release_buffer
(
struct
wg_parser_stream
*
stream
)
{
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_release_buffer
,
stream
);
}
void
wg_parser_stream_notify_qos
(
struct
wg_parser_stream
*
stream
,
bool
underflow
,
double
proportion
,
int64_t
diff
,
uint64_t
timestamp
)
{
struct
wg_parser_stream_notify_qos_params
params
=
{
.
stream
=
stream
,
.
underflow
=
underflow
,
.
proportion
=
proportion
,
.
diff
=
diff
,
.
timestamp
=
timestamp
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_notify_qos
,
&
params
);
}
uint64_t
wg_parser_stream_get_duration
(
struct
wg_parser_stream
*
stream
)
{
struct
wg_parser_stream_get_duration_params
params
=
{
.
stream
=
stream
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_get_duration
,
&
params
);
return
params
.
duration
;
}
void
wg_parser_stream_seek
(
struct
wg_parser_stream
*
stream
,
double
rate
,
uint64_t
start_pos
,
uint64_t
stop_pos
,
DWORD
start_flags
,
DWORD
stop_flags
)
{
struct
wg_parser_stream_seek_params
params
=
{
.
stream
=
stream
,
.
rate
=
rate
,
.
start_pos
=
start_pos
,
.
stop_pos
=
stop_pos
,
.
start_flags
=
start_flags
,
.
stop_flags
=
stop_flags
,
};
__wine_unix_call
(
unix_handle
,
unix_wg_parser_stream_seek
,
&
params
);
}
BOOL
WINAPI
DllMain
(
HINSTANCE
instance
,
DWORD
reason
,
void
*
reserved
)
{
if
(
reason
==
DLL_PROCESS_ATTACH
)
{
DisableThreadLibraryCalls
(
instance
);
__wine_init_unix_lib
(
instance
,
reason
,
NULL
,
&
unix_funcs
);
NtQueryVirtualMemory
(
GetCurrentProcess
(),
instance
,
MemoryWineUnixFuncs
,
&
unix_handle
,
sizeof
(
unix_handle
),
NULL
);
}
return
TRUE
;
}
...
...
dlls/winegstreamer/media_source.c
View file @
4ba31162
...
...
@@ -357,7 +357,7 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
IMFMediaTypeHandler_GetCurrentMediaType
(
mth
,
&
current_mt
);
mf_media_type_to_wg_format
(
current_mt
,
&
format
);
unix_funcs
->
wg_parser_stream_enable
(
stream
->
wg_stream
,
&
format
);
wg_parser_stream_enable
(
stream
->
wg_stream
,
&
format
);
IMFMediaType_Release
(
current_mt
);
IMFMediaTypeHandler_Release
(
mth
);
...
...
@@ -385,9 +385,9 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
source
->
state
=
SOURCE_RUNNING
;
if
(
position
->
vt
==
VT_I8
)
unix_funcs
->
wg_parser_stream_seek
(
source
->
streams
[
0
]
->
wg_stream
,
1
.
0
,
position
->
hVal
.
QuadPart
,
0
,
AM_SEEKING_AbsolutePositioning
,
AM_SEEKING_NoPositioning
);
unix_funcs
->
wg_parser_end_flush
(
source
->
wg_parser
);
wg_parser_stream_seek
(
source
->
streams
[
0
]
->
wg_stream
,
1
.
0
,
position
->
hVal
.
QuadPart
,
0
,
AM_SEEKING_AbsolutePositioning
,
AM_SEEKING_NoPositioning
);
wg_parser_end_flush
(
source
->
wg_parser
);
for
(
i
=
0
;
i
<
source
->
stream_count
;
i
++
)
flush_token_queue
(
source
->
streams
[
i
],
position
->
vt
==
VT_EMPTY
);
...
...
@@ -415,7 +415,7 @@ static void stop_pipeline(struct media_source *source)
{
unsigned
int
i
;
unix_funcs
->
wg_parser_begin_flush
(
source
->
wg_parser
);
wg_parser_begin_flush
(
source
->
wg_parser
);
for
(
i
=
0
;
i
<
source
->
stream_count
;
i
++
)
{
...
...
@@ -423,7 +423,7 @@ static void stop_pipeline(struct media_source *source)
if
(
stream
->
state
!=
STREAM_INACTIVE
)
{
IMFMediaEventQueue_QueueEventParamVar
(
stream
->
event_queue
,
MEStreamStopped
,
&
GUID_NULL
,
S_OK
,
NULL
);
unix_funcs
->
wg_parser_stream_disable
(
stream
->
wg_stream
);
wg_parser_stream_disable
(
stream
->
wg_stream
);
}
}
...
...
@@ -490,13 +490,13 @@ static void send_buffer(struct media_stream *stream, const struct wg_parser_even
goto
out
;
}
if
(
!
unix_funcs
->
wg_parser_stream_copy_buffer
(
stream
->
wg_stream
,
data
,
0
,
event
->
u
.
buffer
.
size
))
if
(
!
wg_parser_stream_copy_buffer
(
stream
->
wg_stream
,
data
,
0
,
event
->
u
.
buffer
.
size
))
{
unix_funcs
->
wg_parser_stream_release_buffer
(
stream
->
wg_stream
);
wg_parser_stream_release_buffer
(
stream
->
wg_stream
);
IMFMediaBuffer_Unlock
(
buffer
);
goto
out
;
}
unix_funcs
->
wg_parser_stream_release_buffer
(
stream
->
wg_stream
);
wg_parser_stream_release_buffer
(
stream
->
wg_stream
);
if
(
FAILED
(
hr
=
IMFMediaBuffer_Unlock
(
buffer
)))
{
...
...
@@ -536,7 +536,7 @@ static void wait_on_sample(struct media_stream *stream, IUnknown *token)
for
(;;)
{
if
(
!
unix_funcs
->
wg_parser_stream_get_event
(
stream
->
wg_stream
,
&
event
))
if
(
!
wg_parser_stream_get_event
(
stream
->
wg_stream
,
&
event
))
return
;
TRACE
(
"Got event of type %#x.
\n
"
,
event
.
type
);
...
...
@@ -628,7 +628,7 @@ static DWORD CALLBACK read_thread(void *arg)
uint32_t
size
;
HRESULT
hr
;
if
(
!
unix_funcs
->
wg_parser_get_next_read_offset
(
source
->
wg_parser
,
&
offset
,
&
size
))
if
(
!
wg_parser_get_next_read_offset
(
source
->
wg_parser
,
&
offset
,
&
size
))
continue
;
if
(
offset
>=
file_size
)
...
...
@@ -650,7 +650,7 @@ static DWORD CALLBACK read_thread(void *arg)
ERR
(
"Failed to read %u bytes at offset %I64u, hr %#x.
\n
"
,
size
,
offset
,
hr
);
else
if
(
ret_size
!=
size
)
ERR
(
"Unexpected short read: requested %u bytes, got %u.
\n
"
,
size
,
ret_size
);
unix_funcs
->
wg_parser_push_data
(
source
->
wg_parser
,
SUCCEEDED
(
hr
)
?
data
:
NULL
,
ret_size
);
wg_parser_push_data
(
source
->
wg_parser
,
SUCCEEDED
(
hr
)
?
data
:
NULL
,
ret_size
);
}
free
(
data
);
...
...
@@ -867,7 +867,7 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
unsigned
int
i
;
HRESULT
hr
;
unix_funcs
->
wg_parser_stream_get_preferred_format
(
stream
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
stream
->
wg_stream
,
&
format
);
if
(
format
.
major_type
==
WG_MAJOR_TYPE_VIDEO
)
{
...
...
@@ -1327,7 +1327,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
source
->
state
=
SOURCE_SHUTDOWN
;
unix_funcs
->
wg_parser_disconnect
(
source
->
wg_parser
);
wg_parser_disconnect
(
source
->
wg_parser
);
source
->
read_thread_shutdown
=
true
;
WaitForSingleObject
(
source
->
read_thread
,
INFINITE
);
...
...
@@ -1350,7 +1350,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
IMFMediaStream_Release
(
&
stream
->
IMFMediaStream_iface
);
}
unix_funcs
->
wg_parser_destroy
(
source
->
wg_parser
);
wg_parser_destroy
(
source
->
wg_parser
);
free
(
source
->
streams
);
...
...
@@ -1427,7 +1427,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
* never deselects it). Remove buffering limits from decodebin in order to
* account for this. Note that this does leak memory, but the same memory
* leak occurs with native. */
if
(
!
(
parser
=
unix_funcs
->
wg_parser_create
(
WG_PARSER_DECODEBIN
,
true
)))
if
(
!
(
parser
=
wg_parser_create
(
WG_PARSER_DECODEBIN
,
true
)))
{
hr
=
E_OUTOFMEMORY
;
goto
fail
;
...
...
@@ -1438,10 +1438,10 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
object
->
state
=
SOURCE_OPENING
;
if
(
FAILED
(
hr
=
unix_funcs
->
wg_parser_connect
(
parser
,
file_size
)))
if
(
FAILED
(
hr
=
wg_parser_connect
(
parser
,
file_size
)))
goto
fail
;
stream_count
=
unix_funcs
->
wg_parser_get_stream_count
(
parser
);
stream_count
=
wg_parser_get_stream_count
(
parser
);
if
(
!
(
object
->
streams
=
calloc
(
stream_count
,
sizeof
(
*
object
->
streams
))))
{
...
...
@@ -1451,7 +1451,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
for
(
i
=
0
;
i
<
stream_count
;
++
i
)
{
if
(
FAILED
(
hr
=
new_media_stream
(
object
,
unix_funcs
->
wg_parser_get_stream
(
parser
,
i
),
i
,
&
object
->
streams
[
i
])))
if
(
FAILED
(
hr
=
new_media_stream
(
object
,
wg_parser_get_stream
(
parser
,
i
),
i
,
&
object
->
streams
[
i
])))
goto
fail
;
if
(
FAILED
(
hr
=
media_stream_init_desc
(
object
->
streams
[
i
])))
...
...
@@ -1487,7 +1487,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
for
(
i
=
0
;
i
<
object
->
stream_count
;
i
++
)
total_pres_time
=
max
(
total_pres_time
,
unix_funcs
->
wg_parser_stream_get_duration
(
object
->
streams
[
i
]
->
wg_stream
));
wg_parser_stream_get_duration
(
object
->
streams
[
i
]
->
wg_stream
));
if
(
object
->
stream_count
)
IMFPresentationDescriptor_SetUINT64
(
object
->
pres_desc
,
&
MF_PD_DURATION
,
total_pres_time
);
...
...
@@ -1518,7 +1518,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
}
free
(
object
->
streams
);
if
(
stream_count
!=
UINT_MAX
)
unix_funcs
->
wg_parser_disconnect
(
object
->
wg_parser
);
wg_parser_disconnect
(
object
->
wg_parser
);
if
(
object
->
read_thread
)
{
object
->
read_thread_shutdown
=
true
;
...
...
@@ -1526,7 +1526,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
CloseHandle
(
object
->
read_thread
);
}
if
(
object
->
wg_parser
)
unix_funcs
->
wg_parser_destroy
(
object
->
wg_parser
);
wg_parser_destroy
(
object
->
wg_parser
);
if
(
object
->
async_commands_queue
)
MFUnlockWorkQueue
(
object
->
async_commands_queue
);
if
(
object
->
event_queue
)
...
...
dlls/winegstreamer/quartz_parser.c
View file @
4ba31162
...
...
@@ -623,7 +623,7 @@ static HRESULT send_sample(struct parser_source *pin, IMediaSample *sample,
IMediaSample_GetPointer
(
sample
,
&
ptr
);
if
(
!
unix_funcs
->
wg_parser_stream_copy_buffer
(
pin
->
wg_stream
,
ptr
,
offset
,
size
))
if
(
!
wg_parser_stream_copy_buffer
(
pin
->
wg_stream
,
ptr
,
offset
,
size
))
{
/* The GStreamer pin has been flushed. */
return
S_OK
;
...
...
@@ -732,7 +732,7 @@ static void send_buffer(struct parser_source *pin, const struct wg_parser_event
}
}
unix_funcs
->
wg_parser_stream_release_buffer
(
pin
->
wg_stream
);
wg_parser_stream_release_buffer
(
pin
->
wg_stream
);
}
static
DWORD
CALLBACK
stream_thread
(
void
*
arg
)
...
...
@@ -748,7 +748,7 @@ static DWORD CALLBACK stream_thread(void *arg)
EnterCriticalSection
(
&
pin
->
flushing_cs
);
if
(
!
unix_funcs
->
wg_parser_stream_get_event
(
pin
->
wg_stream
,
&
event
))
if
(
!
wg_parser_stream_get_event
(
pin
->
wg_stream
,
&
event
))
{
LeaveCriticalSection
(
&
pin
->
flushing_cs
);
continue
;
...
...
@@ -799,7 +799,7 @@ static DWORD CALLBACK read_thread(void *arg)
uint32_t
size
;
HRESULT
hr
;
if
(
!
unix_funcs
->
wg_parser_get_next_read_offset
(
filter
->
wg_parser
,
&
offset
,
&
size
))
if
(
!
wg_parser_get_next_read_offset
(
filter
->
wg_parser
,
&
offset
,
&
size
))
continue
;
if
(
offset
>=
file_size
)
...
...
@@ -817,7 +817,7 @@ static DWORD CALLBACK read_thread(void *arg)
if
(
FAILED
(
hr
))
ERR
(
"Failed to read %u bytes at offset %I64u, hr %#x.
\n
"
,
size
,
offset
,
hr
);
unix_funcs
->
wg_parser_push_data
(
filter
->
wg_parser
,
SUCCEEDED
(
hr
)
?
data
:
NULL
,
size
);
wg_parser_push_data
(
filter
->
wg_parser
,
SUCCEEDED
(
hr
)
?
data
:
NULL
,
size
);
}
free
(
data
);
...
...
@@ -869,7 +869,7 @@ static void parser_destroy(struct strmbase_filter *iface)
IAsyncReader_Release
(
filter
->
reader
);
filter
->
reader
=
NULL
;
unix_funcs
->
wg_parser_destroy
(
filter
->
wg_parser
);
wg_parser_destroy
(
filter
->
wg_parser
);
strmbase_sink_cleanup
(
&
filter
->
sink
);
strmbase_filter_cleanup
(
&
filter
->
filter
);
...
...
@@ -887,7 +887,7 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface)
return
S_OK
;
filter
->
streaming
=
true
;
unix_funcs
->
wg_parser_end_flush
(
filter
->
wg_parser
);
wg_parser_end_flush
(
filter
->
wg_parser
);
/* DirectShow retains the old seek positions, but resets to them every time
* it transitions from stopped -> paused. */
...
...
@@ -895,7 +895,7 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface)
seeking
=
&
filter
->
sources
[
0
]
->
seek
;
if
(
seeking
->
llStop
)
stop_flags
=
AM_SEEKING_AbsolutePositioning
;
unix_funcs
->
wg_parser_stream_seek
(
filter
->
sources
[
0
]
->
wg_stream
,
seeking
->
dRate
,
wg_parser_stream_seek
(
filter
->
sources
[
0
]
->
wg_stream
,
seeking
->
dRate
,
seeking
->
llCurrent
,
seeking
->
llStop
,
AM_SEEKING_AbsolutePositioning
,
stop_flags
);
for
(
i
=
0
;
i
<
filter
->
source_count
;
++
i
)
...
...
@@ -923,7 +923,7 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface)
return
S_OK
;
filter
->
streaming
=
false
;
unix_funcs
->
wg_parser_begin_flush
(
filter
->
wg_parser
);
wg_parser_begin_flush
(
filter
->
wg_parser
);
for
(
i
=
0
;
i
<
filter
->
source_count
;
++
i
)
{
...
...
@@ -978,7 +978,7 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons
filter
->
sink_connected
=
true
;
filter
->
read_thread
=
CreateThread
(
NULL
,
0
,
read_thread
,
filter
,
0
,
NULL
);
if
(
FAILED
(
hr
=
unix_funcs
->
wg_parser_connect
(
filter
->
wg_parser
,
file_size
)))
if
(
FAILED
(
hr
=
wg_parser_connect
(
filter
->
wg_parser
,
file_size
)))
goto
err
;
if
(
!
filter
->
init_gst
(
filter
))
...
...
@@ -991,7 +991,7 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons
{
struct
parser_source
*
pin
=
filter
->
sources
[
i
];
pin
->
seek
.
llDuration
=
pin
->
seek
.
llStop
=
unix_funcs
->
wg_parser_stream_get_duration
(
pin
->
wg_stream
);
pin
->
seek
.
llDuration
=
pin
->
seek
.
llStop
=
wg_parser_stream_get_duration
(
pin
->
wg_stream
);
pin
->
seek
.
llCurrent
=
0
;
}
...
...
@@ -1026,11 +1026,11 @@ static BOOL decodebin_parser_filter_init_gst(struct parser *filter)
unsigned
int
i
,
stream_count
;
WCHAR
source_name
[
20
];
stream_count
=
unix_funcs
->
wg_parser_get_stream_count
(
parser
);
stream_count
=
wg_parser_get_stream_count
(
parser
);
for
(
i
=
0
;
i
<
stream_count
;
++
i
)
{
swprintf
(
source_name
,
ARRAY_SIZE
(
source_name
),
L"Stream %02u"
,
i
);
if
(
!
create_pin
(
filter
,
unix_funcs
->
wg_parser_get_stream
(
parser
,
i
),
source_name
))
if
(
!
create_pin
(
filter
,
wg_parser_get_stream
(
parser
,
i
),
source_name
))
return
FALSE
;
}
...
...
@@ -1069,7 +1069,7 @@ static HRESULT decodebin_parser_source_get_media_type(struct parser_source *pin,
WG_VIDEO_FORMAT_RGB15
,
};
unix_funcs
->
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
memset
(
mt
,
0
,
sizeof
(
AM_MEDIA_TYPE
));
...
...
@@ -1115,7 +1115,7 @@ HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out)
if
(
!
(
object
=
calloc
(
1
,
sizeof
(
*
object
))))
return
E_OUTOFMEMORY
;
if
(
!
(
object
->
wg_parser
=
unix_funcs
->
wg_parser_create
(
WG_PARSER_DECODEBIN
,
false
)))
if
(
!
(
object
->
wg_parser
=
wg_parser_create
(
WG_PARSER_DECODEBIN
,
false
)))
{
free
(
object
);
return
E_OUTOFMEMORY
;
...
...
@@ -1205,7 +1205,7 @@ static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface)
{
struct
parser_source
*
pin
=
impl_from_IMediaSeeking
(
iface
);
unix_funcs
->
wg_parser_stream_seek
(
pin
->
wg_stream
,
pin
->
seek
.
dRate
,
0
,
0
,
wg_parser_stream_seek
(
pin
->
wg_stream
,
pin
->
seek
.
dRate
,
0
,
0
,
AM_SEEKING_NoPositioning
,
AM_SEEKING_NoPositioning
);
return
S_OK
;
}
...
...
@@ -1247,7 +1247,7 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
if
(
!
(
current_flags
&
AM_SEEKING_NoFlush
))
{
unix_funcs
->
wg_parser_begin_flush
(
filter
->
wg_parser
);
wg_parser_begin_flush
(
filter
->
wg_parser
);
for
(
i
=
0
;
i
<
filter
->
source_count
;
++
i
)
{
...
...
@@ -1269,12 +1269,12 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
SourceSeekingImpl_SetPositions
(
iface
,
current
,
current_flags
,
stop
,
stop_flags
);
unix_funcs
->
wg_parser_stream_seek
(
pin
->
wg_stream
,
pin
->
seek
.
dRate
,
wg_parser_stream_seek
(
pin
->
wg_stream
,
pin
->
seek
.
dRate
,
pin
->
seek
.
llCurrent
,
pin
->
seek
.
llStop
,
current_flags
,
stop_flags
);
if
(
!
(
current_flags
&
AM_SEEKING_NoFlush
))
{
unix_funcs
->
wg_parser_end_flush
(
filter
->
wg_parser
);
wg_parser_end_flush
(
filter
->
wg_parser
);
for
(
i
=
0
;
i
<
filter
->
source_count
;
++
i
)
{
...
...
@@ -1383,7 +1383,7 @@ static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFil
/* GST_QOS_TYPE_OVERFLOW is also used for buffers that arrive on time, but
* DirectShow filters might use Famine, so check that there actually is an
* underrun. */
unix_funcs
->
wg_parser_stream_notify_qos
(
pin
->
wg_stream
,
q
.
Type
==
Famine
&&
q
.
Proportion
<
1000
,
wg_parser_stream_notify_qos
(
pin
->
wg_stream
,
q
.
Type
==
Famine
&&
q
.
Proportion
<
1000
,
1000
.
0
/
q
.
Proportion
,
diff
,
timestamp
);
return
S_OK
;
...
...
@@ -1463,7 +1463,7 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface,
ret
=
amt_to_wg_format
(
&
pin
->
pin
.
pin
.
mt
,
&
format
);
assert
(
ret
);
unix_funcs
->
wg_parser_stream_enable
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_enable
(
pin
->
wg_stream
,
&
format
);
/* We do need to drop any buffers that might have been sent with the old
* caps, but this will be handled in parser_init_stream(). */
...
...
@@ -1478,7 +1478,7 @@ static void source_disconnect(struct strmbase_source *iface)
{
struct
parser_source
*
pin
=
impl_source_from_IPin
(
&
iface
->
pin
.
IPin_iface
);
unix_funcs
->
wg_parser_stream_disable
(
pin
->
wg_stream
);
wg_parser_stream_disable
(
pin
->
wg_stream
);
}
static
void
free_source_pin
(
struct
parser_source
*
pin
)
...
...
@@ -1544,7 +1544,7 @@ static HRESULT GST_RemoveOutputPins(struct parser *This)
if
(
!
This
->
sink_connected
)
return
S_OK
;
unix_funcs
->
wg_parser_disconnect
(
This
->
wg_parser
);
wg_parser_disconnect
(
This
->
wg_parser
);
/* read_thread() needs to stay alive to service any read requests GStreamer
* sends, so we can only shut it down after GStreamer stops. */
...
...
@@ -1597,7 +1597,7 @@ static BOOL wave_parser_filter_init_gst(struct parser *filter)
{
struct
wg_parser
*
parser
=
filter
->
wg_parser
;
if
(
!
create_pin
(
filter
,
unix_funcs
->
wg_parser_get_stream
(
parser
,
0
),
L"output"
))
if
(
!
create_pin
(
filter
,
wg_parser_get_stream
(
parser
,
0
),
L"output"
))
return
FALSE
;
return
TRUE
;
...
...
@@ -1609,7 +1609,7 @@ static HRESULT wave_parser_source_query_accept(struct parser_source *pin, const
AM_MEDIA_TYPE
pad_mt
;
HRESULT
hr
;
unix_funcs
->
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
if
(
!
amt_from_wg_format
(
&
pad_mt
,
&
format
))
return
E_OUTOFMEMORY
;
hr
=
compare_media_types
(
mt
,
&
pad_mt
)
?
S_OK
:
S_FALSE
;
...
...
@@ -1624,7 +1624,7 @@ static HRESULT wave_parser_source_get_media_type(struct parser_source *pin,
if
(
index
>
0
)
return
VFW_S_NO_MORE_ITEMS
;
unix_funcs
->
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
if
(
!
amt_from_wg_format
(
mt
,
&
format
))
return
E_OUTOFMEMORY
;
return
S_OK
;
...
...
@@ -1640,7 +1640,7 @@ HRESULT wave_parser_create(IUnknown *outer, IUnknown **out)
if
(
!
(
object
=
calloc
(
1
,
sizeof
(
*
object
))))
return
E_OUTOFMEMORY
;
if
(
!
(
object
->
wg_parser
=
unix_funcs
->
wg_parser_create
(
WG_PARSER_WAVPARSE
,
false
)))
if
(
!
(
object
->
wg_parser
=
wg_parser_create
(
WG_PARSER_WAVPARSE
,
false
)))
{
free
(
object
);
return
E_OUTOFMEMORY
;
...
...
@@ -1678,11 +1678,11 @@ static BOOL avi_splitter_filter_init_gst(struct parser *filter)
uint32_t
i
,
stream_count
;
WCHAR
source_name
[
20
];
stream_count
=
unix_funcs
->
wg_parser_get_stream_count
(
parser
);
stream_count
=
wg_parser_get_stream_count
(
parser
);
for
(
i
=
0
;
i
<
stream_count
;
++
i
)
{
swprintf
(
source_name
,
ARRAY_SIZE
(
source_name
),
L"Stream %02u"
,
i
);
if
(
!
create_pin
(
filter
,
unix_funcs
->
wg_parser_get_stream
(
parser
,
i
),
source_name
))
if
(
!
create_pin
(
filter
,
wg_parser_get_stream
(
parser
,
i
),
source_name
))
return
FALSE
;
}
...
...
@@ -1695,7 +1695,7 @@ static HRESULT avi_splitter_source_query_accept(struct parser_source *pin, const
AM_MEDIA_TYPE
pad_mt
;
HRESULT
hr
;
unix_funcs
->
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
if
(
!
amt_from_wg_format
(
&
pad_mt
,
&
format
))
return
E_OUTOFMEMORY
;
hr
=
compare_media_types
(
mt
,
&
pad_mt
)
?
S_OK
:
S_FALSE
;
...
...
@@ -1710,7 +1710,7 @@ static HRESULT avi_splitter_source_get_media_type(struct parser_source *pin,
if
(
index
>
0
)
return
VFW_S_NO_MORE_ITEMS
;
unix_funcs
->
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
if
(
!
amt_from_wg_format
(
mt
,
&
format
))
return
E_OUTOFMEMORY
;
return
S_OK
;
...
...
@@ -1726,7 +1726,7 @@ HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out)
if
(
!
(
object
=
calloc
(
1
,
sizeof
(
*
object
))))
return
E_OUTOFMEMORY
;
if
(
!
(
object
->
wg_parser
=
unix_funcs
->
wg_parser_create
(
WG_PARSER_AVIDEMUX
,
false
)))
if
(
!
(
object
->
wg_parser
=
wg_parser_create
(
WG_PARSER_AVIDEMUX
,
false
)))
{
free
(
object
);
return
E_OUTOFMEMORY
;
...
...
@@ -1767,7 +1767,7 @@ static BOOL mpeg_splitter_filter_init_gst(struct parser *filter)
{
struct
wg_parser
*
parser
=
filter
->
wg_parser
;
if
(
!
create_pin
(
filter
,
unix_funcs
->
wg_parser_get_stream
(
parser
,
0
),
L"Audio"
))
if
(
!
create_pin
(
filter
,
wg_parser_get_stream
(
parser
,
0
),
L"Audio"
))
return
FALSE
;
return
TRUE
;
...
...
@@ -1779,7 +1779,7 @@ static HRESULT mpeg_splitter_source_query_accept(struct parser_source *pin, cons
AM_MEDIA_TYPE
pad_mt
;
HRESULT
hr
;
unix_funcs
->
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
if
(
!
amt_from_wg_format
(
&
pad_mt
,
&
format
))
return
E_OUTOFMEMORY
;
hr
=
compare_media_types
(
mt
,
&
pad_mt
)
?
S_OK
:
S_FALSE
;
...
...
@@ -1794,7 +1794,7 @@ static HRESULT mpeg_splitter_source_get_media_type(struct parser_source *pin,
if
(
index
>
0
)
return
VFW_S_NO_MORE_ITEMS
;
unix_funcs
->
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
wg_parser_stream_get_preferred_format
(
pin
->
wg_stream
,
&
format
);
if
(
!
amt_from_wg_format
(
mt
,
&
format
))
return
E_OUTOFMEMORY
;
return
S_OK
;
...
...
@@ -1833,7 +1833,7 @@ HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out)
if
(
!
(
object
=
calloc
(
1
,
sizeof
(
*
object
))))
return
E_OUTOFMEMORY
;
if
(
!
(
object
->
wg_parser
=
unix_funcs
->
wg_parser_create
(
WG_PARSER_MPEGAUDIOPARSE
,
false
)))
if
(
!
(
object
->
wg_parser
=
wg_parser_create
(
WG_PARSER_MPEGAUDIOPARSE
,
false
)))
{
free
(
object
);
return
E_OUTOFMEMORY
;
...
...
dlls/winegstreamer/unixlib.h
View file @
4ba31162
...
...
@@ -24,9 +24,12 @@
#include <stdbool.h>
#include <stdint.h>
#include "windef.h"
#include "winternl.h"
#include "wtypes.h"
#include "mmreg.h"
#include "wine/unixlib.h"
struct
wg_format
{
enum
wg_major_type
...
...
@@ -125,41 +128,123 @@ enum wg_parser_type
WG_PARSER_WAVPARSE
,
};
struct
unix_funcs
struct
wg_parser_create_params
{
struct
wg_parser
*
parser
;
enum
wg_parser_type
type
;
bool
unlimited_buffering
;
};
struct
wg_parser_connect_params
{
struct
wg_parser
*
parser
;
UINT64
file_size
;
};
struct
wg_parser_get_next_read_offset_params
{
struct
wg_parser
*
parser
;
UINT32
size
;
UINT64
offset
;
};
struct
wg_parser_push_data_params
{
struct
wg_parser
*
parser
;
const
void
*
data
;
UINT32
size
;
};
struct
wg_parser_get_stream_count_params
{
struct
wg_parser
*
parser
;
UINT32
count
;
};
struct
wg_parser_get_stream_params
{
struct
wg_parser
*
parser
;
UINT32
index
;
struct
wg_parser_stream
*
stream
;
};
struct
wg_parser_stream_get_preferred_format_params
{
struct
wg_parser_stream
*
stream
;
struct
wg_format
*
format
;
};
struct
wg_parser_stream_enable_params
{
struct
wg_parser_stream
*
stream
;
const
struct
wg_format
*
format
;
};
struct
wg_parser_stream_get_event_params
{
struct
wg_parser_stream
*
stream
;
struct
wg_parser_event
*
event
;
};
struct
wg_parser_stream_copy_buffer_params
{
struct
wg_parser_stream
*
stream
;
void
*
data
;
UINT32
offset
;
UINT32
size
;
};
struct
wg_parser_stream_notify_qos_params
{
struct
wg_parser_stream
*
stream
;
bool
underflow
;
DOUBLE
proportion
;
INT64
diff
;
UINT64
timestamp
;
};
struct
wg_parser_stream_get_duration_params
{
struct
wg_parser_stream
*
stream
;
UINT64
duration
;
};
struct
wg_parser_stream_seek_params
{
struct
wg_parser_stream
*
stream
;
DOUBLE
rate
;
UINT64
start_pos
,
stop_pos
;
DWORD
start_flags
,
stop_flags
;
};
enum
unix_funcs
{
struct
wg_parser
*
(
CDECL
*
wg_parser_create
)(
enum
wg_parser_type
type
,
bool
unlimited_buffering
);
void
(
CDECL
*
wg_parser_destroy
)(
struct
wg_parser
*
parser
);
unix_wg_parser_create
,
unix_wg_parser_destroy
,
HRESULT
(
CDECL
*
wg_parser_connect
)(
struct
wg_parser
*
parser
,
uint64_t
file_size
);
void
(
CDECL
*
wg_parser_disconnect
)(
struct
wg_parser
*
parser
);
unix_wg_parser_connect
,
unix_wg_parser_disconnect
,
void
(
CDECL
*
wg_parser_begin_flush
)(
struct
wg_parser
*
parser
);
void
(
CDECL
*
wg_parser_end_flush
)(
struct
wg_parser
*
parser
);
unix_wg_parser_begin_flush
,
unix_wg_parser_end_flush
,
bool
(
CDECL
*
wg_parser_get_next_read_offset
)(
struct
wg_parser
*
parser
,
uint64_t
*
offset
,
uint32_t
*
size
);
void
(
CDECL
*
wg_parser_push_data
)(
struct
wg_parser
*
parser
,
const
void
*
data
,
uint32_t
size
);
unix_wg_parser_get_next_read_offset
,
unix_wg_parser_push_data
,
u
int32_t
(
CDECL
*
wg_parser_get_stream_count
)(
struct
wg_parser
*
parser
);
struct
wg_parser_stream
*
(
CDECL
*
wg_parser_get_stream
)(
struct
wg_parser
*
parser
,
uint32_t
index
);
u
nix_wg_parser_get_stream_count
,
unix_wg_parser_get_stream
,
void
(
CDECL
*
wg_parser_stream_get_preferred_format
)(
struct
wg_parser_stream
*
stream
,
struct
wg_format
*
format
);
void
(
CDECL
*
wg_parser_stream_enable
)(
struct
wg_parser_stream
*
stream
,
const
struct
wg_format
*
format
);
void
(
CDECL
*
wg_parser_stream_disable
)(
struct
wg_parser_stream
*
stream
);
unix_wg_parser_stream_get_preferred_format
,
unix_wg_parser_stream_enable
,
unix_wg_parser_stream_disable
,
bool
(
CDECL
*
wg_parser_stream_get_event
)(
struct
wg_parser_stream
*
stream
,
struct
wg_parser_event
*
event
);
bool
(
CDECL
*
wg_parser_stream_copy_buffer
)(
struct
wg_parser_stream
*
stream
,
void
*
data
,
uint32_t
offset
,
uint32_t
size
);
void
(
CDECL
*
wg_parser_stream_release_buffer
)(
struct
wg_parser_stream
*
stream
);
void
(
CDECL
*
wg_parser_stream_notify_qos
)(
struct
wg_parser_stream
*
stream
,
bool
underflow
,
double
proportion
,
int64_t
diff
,
uint64_t
timestamp
);
unix_wg_parser_stream_get_event
,
unix_wg_parser_stream_copy_buffer
,
unix_wg_parser_stream_release_buffer
,
unix_wg_parser_stream_notify_qos
,
/* Returns the duration in 100-nanosecond units. */
uint64_t
(
CDECL
*
wg_parser_stream_get_duration
)(
struct
wg_parser_stream
*
stream
);
/* start_pos and stop_pos are in 100-nanosecond units. */
void
(
CDECL
*
wg_parser_stream_seek
)(
struct
wg_parser_stream
*
stream
,
double
rate
,
uint64_t
start_pos
,
uint64_t
stop_pos
,
DWORD
start_flags
,
DWORD
stop_flags
);
unix_wg_parser_stream_get_duration
,
unix_wg_parser_stream_seek
,
};
#endif
/* __WINE_WINEGSTREAMER_UNIXLIB_H */
dlls/winegstreamer/wg_parser.c
View file @
4ba31162
...
...
@@ -34,8 +34,6 @@
#include <gst/video/video.h>
#include <gst/audio/audio.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"
#include "dshow.h"
...
...
@@ -503,18 +501,25 @@ static bool wg_format_compare(const struct wg_format *a, const struct wg_format
return
false
;
}
static
uint32_t
CDECL
wg_parser_get_stream_count
(
struct
wg_parser
*
parser
)
static
NTSTATUS
wg_parser_get_stream_count
(
void
*
args
)
{
return
parser
->
stream_count
;
struct
wg_parser_get_stream_count_params
*
params
=
args
;
params
->
count
=
params
->
parser
->
stream_count
;
return
S_OK
;
}
static
struct
wg_parser_stream
*
CDECL
wg_parser_get_stream
(
struct
wg_parser
*
parser
,
uint32_t
index
)
static
NTSTATUS
wg_parser_get_stream
(
void
*
args
)
{
return
parser
->
streams
[
index
];
struct
wg_parser_get_stream_params
*
params
=
args
;
params
->
stream
=
params
->
parser
->
streams
[
params
->
index
];
return
S_OK
;
}
static
void
CDECL
wg_parser_begin_flush
(
struct
wg_parser
*
parser
)
static
NTSTATUS
wg_parser_begin_flush
(
void
*
args
)
{
struct
wg_parser
*
parser
=
args
;
unsigned
int
i
;
pthread_mutex_lock
(
&
parser
->
mutex
);
...
...
@@ -526,18 +531,26 @@ static void CDECL wg_parser_begin_flush(struct wg_parser *parser)
if
(
parser
->
streams
[
i
]
->
enabled
)
pthread_cond_signal
(
&
parser
->
streams
[
i
]
->
event_cond
);
}
return
S_OK
;
}
static
void
CDECL
wg_parser_end_flush
(
struct
wg_parser
*
parser
)
static
NTSTATUS
wg_parser_end_flush
(
void
*
args
)
{
struct
wg_parser
*
parser
=
args
;
pthread_mutex_lock
(
&
parser
->
mutex
);
parser
->
flushing
=
false
;
pthread_mutex_unlock
(
&
parser
->
mutex
);
return
S_OK
;
}
static
bool
CDECL
wg_parser_get_next_read_offset
(
struct
wg_parser
*
parser
,
uint64_t
*
offset
,
uint32_t
*
size
)
static
NTSTATUS
wg_parser_get_next_read_offset
(
void
*
args
)
{
struct
wg_parser_get_next_read_offset_params
*
params
=
args
;
struct
wg_parser
*
parser
=
params
->
parser
;
pthread_mutex_lock
(
&
parser
->
mutex
);
while
(
parser
->
sink_connected
&&
!
parser
->
read_request
.
data
)
...
...
@@ -546,19 +559,23 @@ static bool CDECL wg_parser_get_next_read_offset(struct wg_parser *parser,
if
(
!
parser
->
sink_connected
)
{
pthread_mutex_unlock
(
&
parser
->
mutex
);
return
false
;
return
VFW_E_WRONG_STATE
;
}
*
offset
=
parser
->
read_request
.
offset
;
*
size
=
parser
->
read_request
.
size
;
params
->
offset
=
parser
->
read_request
.
offset
;
params
->
size
=
parser
->
read_request
.
size
;
pthread_mutex_unlock
(
&
parser
->
mutex
);
return
true
;
return
S_OK
;
}
static
void
CDECL
wg_parser_push_data
(
struct
wg_parser
*
parser
,
const
void
*
data
,
uint32_t
size
)
static
NTSTATUS
wg_parser_push_data
(
void
*
args
)
{
const
struct
wg_parser_push_data_params
*
params
=
args
;
struct
wg_parser
*
parser
=
params
->
parser
;
const
void
*
data
=
params
->
data
;
uint32_t
size
=
params
->
size
;
pthread_mutex_lock
(
&
parser
->
mutex
);
parser
->
read_request
.
size
=
size
;
parser
->
read_request
.
done
=
true
;
...
...
@@ -568,15 +585,24 @@ static void CDECL wg_parser_push_data(struct wg_parser *parser,
parser
->
read_request
.
data
=
NULL
;
pthread_mutex_unlock
(
&
parser
->
mutex
);
pthread_cond_signal
(
&
parser
->
read_done_cond
);
return
S_OK
;
}
static
void
CDECL
wg_parser_stream_get_preferred_format
(
struct
wg_parser_stream
*
stream
,
struct
wg_format
*
format
)
static
NTSTATUS
wg_parser_stream_get_preferred_format
(
void
*
args
)
{
*
format
=
stream
->
preferred_format
;
const
struct
wg_parser_stream_get_preferred_format_params
*
params
=
args
;
*
params
->
format
=
params
->
stream
->
preferred_format
;
return
S_OK
;
}
static
void
CDECL
wg_parser_stream_enable
(
struct
wg_parser_stream
*
stream
,
const
struct
wg_format
*
format
)
static
NTSTATUS
wg_parser_stream_enable
(
void
*
args
)
{
const
struct
wg_parser_stream_enable_params
*
params
=
args
;
struct
wg_parser_stream
*
stream
=
params
->
stream
;
const
struct
wg_format
*
format
=
params
->
format
;
stream
->
current_format
=
*
format
;
stream
->
enabled
=
true
;
...
...
@@ -607,15 +633,21 @@ static void CDECL wg_parser_stream_enable(struct wg_parser_stream *stream, const
}
gst_pad_push_event
(
stream
->
my_sink
,
gst_event_new_reconfigure
());
return
S_OK
;
}
static
void
CDECL
wg_parser_stream_disable
(
struct
wg_parser_stream
*
stream
)
static
NTSTATUS
wg_parser_stream_disable
(
void
*
args
)
{
struct
wg_parser_stream
*
stream
=
args
;
stream
->
enabled
=
false
;
return
S_OK
;
}
static
bool
CDECL
wg_parser_stream_get_event
(
struct
wg_parser_stream
*
stream
,
struct
wg_parser_event
*
event
)
static
NTSTATUS
wg_parser_stream_get_event
(
void
*
args
)
{
const
struct
wg_parser_stream_get_event_params
*
params
=
args
;
struct
wg_parser_stream
*
stream
=
params
->
stream
;
struct
wg_parser
*
parser
=
stream
->
parser
;
pthread_mutex_lock
(
&
parser
->
mutex
);
...
...
@@ -627,10 +659,10 @@ static bool CDECL wg_parser_stream_get_event(struct wg_parser_stream *stream, st
{
pthread_mutex_unlock
(
&
parser
->
mutex
);
GST_DEBUG
(
"Filter is flushing.
\n
"
);
return
false
;
return
VFW_E_WRONG_STATE
;
}
*
event
=
stream
->
event
;
*
params
->
event
=
stream
->
event
;
if
(
stream
->
event
.
type
!=
WG_PARSER_EVENT_BUFFER
)
{
...
...
@@ -639,33 +671,37 @@ static bool CDECL wg_parser_stream_get_event(struct wg_parser_stream *stream, st
}
pthread_mutex_unlock
(
&
parser
->
mutex
);
return
true
;
return
S_OK
;
}
static
bool
CDECL
wg_parser_stream_copy_buffer
(
struct
wg_parser_stream
*
stream
,
void
*
data
,
uint32_t
offset
,
uint32_t
size
)
static
NTSTATUS
wg_parser_stream_copy_buffer
(
void
*
args
)
{
const
struct
wg_parser_stream_copy_buffer_params
*
params
=
args
;
struct
wg_parser_stream
*
stream
=
params
->
stream
;
struct
wg_parser
*
parser
=
stream
->
parser
;
uint32_t
offset
=
params
->
offset
;
uint32_t
size
=
params
->
size
;
pthread_mutex_lock
(
&
parser
->
mutex
);
if
(
!
stream
->
buffer
)
{
pthread_mutex_unlock
(
&
parser
->
mutex
);
return
false
;
return
VFW_E_WRONG_STATE
;
}
assert
(
stream
->
event
.
type
==
WG_PARSER_EVENT_BUFFER
);
assert
(
offset
<
stream
->
map_info
.
size
);
assert
(
offset
+
size
<=
stream
->
map_info
.
size
);
memcpy
(
data
,
stream
->
map_info
.
data
+
offset
,
size
);
memcpy
(
params
->
data
,
stream
->
map_info
.
data
+
offset
,
size
);
pthread_mutex_unlock
(
&
parser
->
mutex
);
return
true
;
return
S_OK
;
}
static
void
CDECL
wg_parser_stream_release_buffer
(
struct
wg_parser_stream
*
stream
)
static
NTSTATUS
wg_parser_stream_release_buffer
(
void
*
args
)
{
struct
wg_parser_stream
*
stream
=
args
;
struct
wg_parser
*
parser
=
stream
->
parser
;
pthread_mutex_lock
(
&
parser
->
mutex
);
...
...
@@ -679,17 +715,24 @@ static void CDECL wg_parser_stream_release_buffer(struct wg_parser_stream *strea
pthread_mutex_unlock
(
&
parser
->
mutex
);
pthread_cond_signal
(
&
stream
->
event_empty_cond
);
return
S_OK
;
}
static
uint64_t
CDECL
wg_parser_stream_get_duration
(
struct
wg_parser_stream
*
stream
)
static
NTSTATUS
wg_parser_stream_get_duration
(
void
*
args
)
{
return
stream
->
duration
;
struct
wg_parser_stream_get_duration_params
*
params
=
args
;
params
->
duration
=
params
->
stream
->
duration
;
return
S_OK
;
}
static
void
CDECL
wg_parser_stream_seek
(
struct
wg_parser_stream
*
stream
,
double
rate
,
uint64_t
start_pos
,
uint64_t
stop_pos
,
DWORD
start_flags
,
DWORD
stop_flags
)
static
NTSTATUS
wg_parser_stream_seek
(
void
*
args
)
{
GstSeekType
start_type
=
GST_SEEK_TYPE_SET
,
stop_type
=
GST_SEEK_TYPE_SET
;
const
struct
wg_parser_stream_seek_params
*
params
=
args
;
DWORD
start_flags
=
params
->
start_flags
;
DWORD
stop_flags
=
params
->
stop_flags
;
GstSeekFlags
flags
=
0
;
if
(
start_flags
&
AM_SEEKING_SeekToKeyFrame
)
...
...
@@ -704,34 +747,39 @@ static void CDECL wg_parser_stream_seek(struct wg_parser_stream *stream, double
if
((
stop_flags
&
AM_SEEKING_PositioningBitsMask
)
==
AM_SEEKING_NoPositioning
)
stop_type
=
GST_SEEK_TYPE_NONE
;
if
(
!
gst_pad_push_event
(
stream
->
my_sink
,
gst_event_new_seek
(
rate
,
GST_FORMAT_TIME
,
flags
,
start_type
,
start_pos
*
100
,
stop_type
,
stop_pos
*
100
)))
if
(
!
gst_pad_push_event
(
params
->
stream
->
my_sink
,
gst_event_new_seek
(
params
->
rate
,
GST_FORMAT_TIME
,
flags
,
start_type
,
params
->
start_pos
*
100
,
stop_type
,
params
->
stop_pos
*
100
)))
GST_ERROR
(
"Failed to seek.
\n
"
);
return
S_OK
;
}
static
void
CDECL
wg_parser_stream_notify_qos
(
struct
wg_parser_stream
*
stream
,
bool
underflow
,
double
proportion
,
int64_t
diff
,
uint64_t
timestamp
)
static
NTSTATUS
wg_parser_stream_notify_qos
(
void
*
args
)
{
const
struct
wg_parser_stream_notify_qos_params
*
params
=
args
;
struct
wg_parser_stream
*
stream
=
params
->
stream
;
GstClockTime
stream_time
;
GstEvent
*
event
;
/* We return timestamps in stream time, i.e. relative to the start of the
* file (or other medium), but gst_event_new_qos() expects the timestamp in
* running time. */
stream_time
=
gst_segment_to_running_time
(
&
stream
->
segment
,
GST_FORMAT_TIME
,
timestamp
*
100
);
stream_time
=
gst_segment_to_running_time
(
&
stream
->
segment
,
GST_FORMAT_TIME
,
params
->
timestamp
*
100
);
if
(
stream_time
==
-
1
)
{
/* This can happen legitimately if the sample falls outside of the
* segment bounds. GStreamer elements shouldn't present the sample in
* that case, but DirectShow doesn't care. */
GST_LOG
(
"Ignoring QoS event.
\n
"
);
return
;
return
S_OK
;
}
if
(
!
(
event
=
gst_event_new_qos
(
underflow
?
GST_QOS_TYPE_UNDERFLOW
:
GST_QOS_TYPE_OVERFLOW
,
p
roportion
,
diff
*
100
,
stream_time
)))
if
(
!
(
event
=
gst_event_new_qos
(
params
->
underflow
?
GST_QOS_TYPE_UNDERFLOW
:
GST_QOS_TYPE_OVERFLOW
,
p
arams
->
proportion
,
params
->
diff
*
100
,
stream_time
)))
GST_ERROR
(
"Failed to create QOS event.
\n
"
);
gst_pad_push_event
(
stream
->
my_sink
,
event
);
return
S_OK
;
}
static
GstAutoplugSelectResult
autoplug_select_cb
(
GstElement
*
bin
,
GstPad
*
pad
,
...
...
@@ -1527,14 +1575,16 @@ static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
return
ret
;
}
static
HRESULT
CDECL
wg_parser_connect
(
struct
wg_parser
*
parser
,
uint64_t
file_size
)
static
NTSTATUS
wg_parser_connect
(
void
*
args
)
{
GstStaticPadTemplate
src_template
=
GST_STATIC_PAD_TEMPLATE
(
"quartz_src"
,
GST_PAD_SRC
,
GST_PAD_ALWAYS
,
GST_STATIC_CAPS_ANY
);
const
struct
wg_parser_connect_params
*
params
=
args
;
struct
wg_parser
*
parser
=
params
->
parser
;
unsigned
int
i
;
int
ret
;
parser
->
file_size
=
file_size
;
parser
->
file_size
=
params
->
file_size
;
parser
->
sink_connected
=
true
;
if
(
!
parser
->
bus
)
...
...
@@ -1684,8 +1734,9 @@ out:
return
E_FAIL
;
}
static
void
CDECL
wg_parser_disconnect
(
struct
wg_parser
*
parser
)
static
NTSTATUS
wg_parser_disconnect
(
void
*
args
)
{
struct
wg_parser
*
parser
=
args
;
unsigned
int
i
;
/* Unblock all of our streams. */
...
...
@@ -1718,6 +1769,8 @@ static void CDECL wg_parser_disconnect(struct wg_parser *parser)
gst_element_set_bus
(
parser
->
container
,
NULL
);
gst_object_unref
(
parser
->
container
);
parser
->
container
=
NULL
;
return
S_OK
;
}
static
BOOL
decodebin_parser_init_gst
(
struct
wg_parser
*
parser
)
...
...
@@ -1878,7 +1931,7 @@ static void init_gstreamer_once(void)
gst_version_string
(),
GST_VERSION_MAJOR
,
GST_VERSION_MINOR
,
GST_VERSION_MICRO
);
}
static
struct
wg_parser
*
CDECL
wg_parser_create
(
enum
wg_parser_type
type
,
bool
unlimited_buffering
)
static
NTSTATUS
wg_parser_create
(
void
*
args
)
{
static
const
init_gst_cb
init_funcs
[]
=
{
...
...
@@ -1889,28 +1942,32 @@ static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type, bool
};
static
pthread_once_t
once
=
PTHREAD_ONCE_INIT
;
struct
wg_parser_create_params
*
params
=
args
;
struct
wg_parser
*
parser
;
if
(
pthread_once
(
&
once
,
init_gstreamer_once
))
return
NUL
L
;
return
E_FAI
L
;
if
(
!
(
parser
=
calloc
(
1
,
sizeof
(
*
parser
))))
return
NULL
;
return
E_OUTOFMEMORY
;
pthread_mutex_init
(
&
parser
->
mutex
,
NULL
);
pthread_cond_init
(
&
parser
->
init_cond
,
NULL
);
pthread_cond_init
(
&
parser
->
read_cond
,
NULL
);
pthread_cond_init
(
&
parser
->
read_done_cond
,
NULL
);
parser
->
flushing
=
true
;
parser
->
init_gst
=
init_funcs
[
type
];
parser
->
unlimited_buffering
=
unlimited_buffering
;
parser
->
init_gst
=
init_funcs
[
params
->
type
];
parser
->
unlimited_buffering
=
params
->
unlimited_buffering
;
GST_DEBUG
(
"Created winegstreamer parser %p.
\n
"
,
parser
);
return
parser
;
params
->
parser
=
parser
;
return
S_OK
;
}
static
void
CDECL
wg_parser_destroy
(
struct
wg_parser
*
parser
)
static
NTSTATUS
wg_parser_destroy
(
void
*
args
)
{
struct
wg_parser
*
parser
=
args
;
if
(
parser
->
bus
)
{
gst_bus_set_sync_handler
(
parser
->
bus
,
NULL
,
NULL
,
NULL
);
...
...
@@ -1923,41 +1980,36 @@ static void CDECL wg_parser_destroy(struct wg_parser *parser)
pthread_cond_destroy
(
&
parser
->
read_done_cond
);
free
(
parser
);
return
S_OK
;
}
static
const
struct
unix_funcs
funcs
=
const
unixlib_entry_t
__wine_unix_call_funcs
[]
=
{
wg_parser_create
,
wg_parser_destroy
,
#define X(name) [unix_ ## name] = name
X
(
wg_parser_create
),
X
(
wg_parser_destroy
),
wg_parser_connect
,
wg_parser_disconnect
,
X
(
wg_parser_connect
)
,
X
(
wg_parser_disconnect
)
,
wg_parser_begin_flush
,
wg_parser_end_flush
,
X
(
wg_parser_begin_flush
)
,
X
(
wg_parser_end_flush
)
,
wg_parser_get_next_read_offset
,
wg_parser_push_data
,
X
(
wg_parser_get_next_read_offset
)
,
X
(
wg_parser_push_data
)
,
wg_parser_get_stream_count
,
wg_parser_get_stream
,
X
(
wg_parser_get_stream_count
)
,
X
(
wg_parser_get_stream
)
,
wg_parser_stream_get_preferred_format
,
wg_parser_stream_enable
,
wg_parser_stream_disable
,
X
(
wg_parser_stream_get_preferred_format
)
,
X
(
wg_parser_stream_enable
)
,
X
(
wg_parser_stream_disable
)
,
wg_parser_stream_get_event
,
wg_parser_stream_copy_buffer
,
wg_parser_stream_release_buffer
,
wg_parser_stream_notify_qos
,
X
(
wg_parser_stream_get_event
)
,
X
(
wg_parser_stream_copy_buffer
)
,
X
(
wg_parser_stream_release_buffer
)
,
X
(
wg_parser_stream_notify_qos
)
,
wg_parser_stream_get_duration
,
wg_parser_stream_seek
,
X
(
wg_parser_stream_get_duration
)
,
X
(
wg_parser_stream_seek
)
,
};
NTSTATUS
CDECL
__wine_init_unix_lib
(
HMODULE
module
,
DWORD
reason
,
const
void
*
ptr_in
,
void
*
ptr_out
)
{
if
(
reason
==
DLL_PROCESS_ATTACH
)
*
(
const
struct
unix_funcs
**
)
ptr_out
=
&
funcs
;
return
STATUS_SUCCESS
;
}
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