Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
efe8bc01
Commit
efe8bc01
authored
Dec 02, 2023
by
Alfred Agrell
Committed by
Alexandre Julliard
Dec 05, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Implement compressed output support in WMSyncReader.
parent
2cdb8cda
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
121 additions
and
28 deletions
+121
-28
wm_reader.c
dlls/winegstreamer/wm_reader.c
+83
-5
wmvcore.c
dlls/wmvcore/tests/wmvcore.c
+38
-23
No files found.
dlls/winegstreamer/wm_reader.c
View file @
efe8bc01
...
...
@@ -30,10 +30,6 @@ struct wm_stream
WMT_STREAM_SELECTION
selection
;
WORD
index
;
bool
eos
;
/* Note that we only pretend to read compressed samples, and instead output
* uncompressed samples regardless of whether we are configured to read
* compressed samples. Rather, the behaviour of the reader objects differs
* in nontrivial ways depending on this field. */
bool
read_compressed
;
IWMReaderAllocatorEx
*
output_allocator
;
...
...
@@ -1541,6 +1537,78 @@ out_destroy_parser:
return
hr
;
}
static
HRESULT
reinit_stream
(
struct
wm_reader
*
reader
,
bool
read_compressed
)
{
wg_parser_t
wg_parser
;
HRESULT
hr
;
WORD
i
;
wg_parser_disconnect
(
reader
->
wg_parser
);
EnterCriticalSection
(
&
reader
->
shutdown_cs
);
reader
->
read_thread_shutdown
=
true
;
LeaveCriticalSection
(
&
reader
->
shutdown_cs
);
WaitForSingleObject
(
reader
->
read_thread
,
INFINITE
);
CloseHandle
(
reader
->
read_thread
);
reader
->
read_thread
=
NULL
;
wg_parser_destroy
(
reader
->
wg_parser
);
reader
->
wg_parser
=
0
;
if
(
!
(
wg_parser
=
wg_parser_create
(
WG_PARSER_DECODEBIN
,
read_compressed
)))
return
E_OUTOFMEMORY
;
reader
->
wg_parser
=
wg_parser
;
reader
->
read_thread_shutdown
=
false
;
if
(
!
(
reader
->
read_thread
=
CreateThread
(
NULL
,
0
,
read_thread
,
reader
,
0
,
NULL
)))
{
hr
=
E_OUTOFMEMORY
;
goto
out_destroy_parser
;
}
if
(
FAILED
(
hr
=
wg_parser_connect
(
reader
->
wg_parser
,
reader
->
file_size
)))
{
ERR
(
"Failed to connect parser, hr %#lx.
\n
"
,
hr
);
goto
out_shutdown_thread
;
}
assert
(
reader
->
stream_count
==
wg_parser_get_stream_count
(
reader
->
wg_parser
));
for
(
i
=
0
;
i
<
reader
->
stream_count
;
++
i
)
{
struct
wm_stream
*
stream
=
&
reader
->
streams
[
i
];
struct
wg_format
format
;
stream
->
wg_stream
=
wg_parser_get_stream
(
reader
->
wg_parser
,
i
);
stream
->
reader
=
reader
;
wg_parser_stream_get_preferred_format
(
stream
->
wg_stream
,
&
format
);
if
(
stream
->
selection
==
WMT_ON
)
wg_parser_stream_enable
(
stream
->
wg_stream
,
read_compressed
?
&
format
:
&
stream
->
format
);
}
/* We probably discarded events because streams weren't enabled yet.
* Now that they're all enabled seek back to the start again. */
wg_parser_stream_seek
(
reader
->
streams
[
0
].
wg_stream
,
1
.
0
,
0
,
0
,
AM_SEEKING_AbsolutePositioning
,
AM_SEEKING_NoPositioning
);
return
S_OK
;
out_shutdown_thread:
EnterCriticalSection
(
&
reader
->
shutdown_cs
);
reader
->
read_thread_shutdown
=
true
;
LeaveCriticalSection
(
&
reader
->
shutdown_cs
);
WaitForSingleObject
(
reader
->
read_thread
,
INFINITE
);
CloseHandle
(
reader
->
read_thread
);
reader
->
read_thread
=
NULL
;
out_destroy_parser:
wg_parser_destroy
(
reader
->
wg_parser
);
reader
->
wg_parser
=
0
;
return
hr
;
}
static
struct
wm_stream
*
wm_reader_get_stream_by_stream_number
(
struct
wm_reader
*
reader
,
WORD
stream_number
)
{
if
(
stream_number
&&
stream_number
<=
reader
->
stream_count
)
...
...
@@ -2352,6 +2420,7 @@ static HRESULT WINAPI reader_SetReadStreamSamples(IWMSyncReader2 *iface, WORD st
}
stream
->
read_compressed
=
compressed
;
reinit_stream
(
reader
,
compressed
);
LeaveCriticalSection
(
&
reader
->
cs
);
return
S_OK
;
...
...
@@ -2397,7 +2466,16 @@ static HRESULT WINAPI reader_SetStreamsSelected(IWMSyncReader2 *iface,
FIXME
(
"Ignoring selection %#x for stream %u; treating as enabled.
\n
"
,
selections
[
i
],
stream_numbers
[
i
]);
TRACE
(
"Enabling stream %u.
\n
"
,
stream_numbers
[
i
]);
wg_parser_stream_enable
(
stream
->
wg_stream
,
&
stream
->
format
);
if
(
stream
->
read_compressed
)
{
struct
wg_format
format
;
wg_parser_stream_get_preferred_format
(
stream
->
wg_stream
,
&
format
);
wg_parser_stream_enable
(
stream
->
wg_stream
,
&
format
);
}
else
{
wg_parser_stream_enable
(
stream
->
wg_stream
,
&
stream
->
format
);
}
}
}
...
...
dlls/wmvcore/tests/wmvcore.c
View file @
efe8bc01
...
...
@@ -455,6 +455,7 @@ struct teststream
HANDLE
file
;
DWORD
input_tid
;
DWORD
main_tid
;
DWORD
input_tid_changes
;
};
static
struct
teststream
*
impl_from_IStream
(
IStream
*
iface
)
...
...
@@ -494,12 +495,10 @@ static HRESULT WINAPI stream_Read(IStream *iface, void *data, ULONG size, ULONG
if
(
winetest_debug
>
2
)
trace
(
"%04lx: IStream::Read(size %lu)
\n
"
,
GetCurrentThreadId
(),
size
);
if
(
!
stream
->
input_tid
)
stream
->
input_tid
=
GetCurrentThreadId
();
else
if
(
stream
->
input_tid
!=
GetCurrentThreadId
())
{
todo_wine_if
(
stream
->
input_tid
==
stream
->
main_tid
)
ok
(
stream
->
input_tid
==
GetCurrentThreadId
(),
"got wrong thread
\n
"
);
++
stream
->
input_tid_changes
;
stream
->
input_tid
=
GetCurrentThreadId
(
);
}
ok
(
size
>
0
,
"Got zero size.
\n
"
);
...
...
@@ -523,12 +522,10 @@ static HRESULT WINAPI stream_Seek(IStream *iface, LARGE_INTEGER offset, DWORD me
if
(
winetest_debug
>
2
)
trace
(
"%04lx: IStream::Seek(offset %I64u, method %#lx)
\n
"
,
GetCurrentThreadId
(),
offset
.
QuadPart
,
method
);
if
(
!
stream
->
input_tid
)
stream
->
input_tid
=
GetCurrentThreadId
();
else
if
(
stream
->
input_tid
!=
GetCurrentThreadId
())
{
todo_wine_if
(
stream
->
input_tid
==
stream
->
main_tid
)
ok
(
stream
->
input_tid
==
GetCurrentThreadId
(),
"got wrong thread
\n
"
);
++
stream
->
input_tid_changes
;
stream
->
input_tid
=
GetCurrentThreadId
(
);
}
GetFileSizeEx
(
stream
->
file
,
&
size
);
...
...
@@ -588,12 +585,10 @@ static HRESULT WINAPI stream_Stat(IStream *iface, STATSTG *stat, DWORD flags)
if
(
winetest_debug
>
1
)
trace
(
"%04lx: IStream::Stat(flags %#lx)
\n
"
,
GetCurrentThreadId
(),
flags
);
if
(
!
stream
->
input_tid
)
stream
->
input_tid
=
GetCurrentThreadId
();
else
if
(
stream
->
input_tid
!=
GetCurrentThreadId
())
{
todo_wine_if
(
stream
->
input_tid
==
stream
->
main_tid
)
ok
(
stream
->
input_tid
==
GetCurrentThreadId
(),
"got wrong thread
\n
"
);
++
stream
->
input_tid_changes
;
stream
->
input_tid
=
GetCurrentThreadId
(
);
}
ok
(
flags
==
STATFLAG_NONAME
,
"Got flags %#lx.
\n
"
,
flags
);
...
...
@@ -1173,6 +1168,7 @@ static void test_sync_reader_settings(void)
IWMSyncReader_Release
(
reader
);
ok
(
stream
.
refcount
==
1
,
"Got outstanding refcount %ld.
\n
"
,
stream
.
refcount
);
todo_wine
ok
(
stream
.
input_tid_changes
==
1
,
"Changed thread %ld times.
\n
"
,
stream
.
input_tid_changes
);
CloseHandle
(
stream
.
file
);
ret
=
DeleteFileW
(
filename
);
ok
(
ret
,
"Failed to delete %s, error %lu.
\n
"
,
debugstr_w
(
filename
),
GetLastError
());
...
...
@@ -1404,7 +1400,6 @@ static void test_sync_reader_streaming(void)
ok
(
stream
.
refcount
==
1
,
"Got outstanding refcount %ld.
\n
"
,
stream
.
refcount
);
stream
.
input_tid
=
0
;
/* FIXME: currently required as Wine calls IStream_Stat synchronously in OpenStream */
SetFilePointer
(
stream
.
file
,
0
,
NULL
,
FILE_BEGIN
);
hr
=
IWMSyncReader_OpenStream
(
reader
,
&
stream
.
IStream_iface
);
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
...
...
@@ -1415,6 +1410,7 @@ static void test_sync_reader_streaming(void)
ok
(
!
ref
,
"Got outstanding refcount %ld.
\n
"
,
ref
);
ok
(
stream
.
refcount
==
1
,
"Got outstanding refcount %ld.
\n
"
,
stream
.
refcount
);
todo_wine
ok
(
stream
.
input_tid_changes
==
1
,
"Changed thread %ld times.
\n
"
,
stream
.
input_tid_changes
);
CloseHandle
(
stream
.
file
);
ret
=
DeleteFileW
(
filename
);
ok
(
ret
,
"Failed to delete %s, error %lu.
\n
"
,
debugstr_w
(
filename
),
GetLastError
());
...
...
@@ -1775,6 +1771,7 @@ static void test_sync_reader_types(void)
ok
(
!
ref
,
"Got outstanding refcount %ld.
\n
"
,
ref
);
ok
(
stream
.
refcount
==
1
,
"Got outstanding refcount %ld.
\n
"
,
stream
.
refcount
);
todo_wine
ok
(
stream
.
input_tid_changes
==
1
,
"Changed thread %ld times.
\n
"
,
stream
.
input_tid_changes
);
CloseHandle
(
stream
.
file
);
ret
=
DeleteFileW
(
filename
);
ok
(
ret
,
"Failed to delete %s, error %lu.
\n
"
,
debugstr_w
(
filename
),
GetLastError
());
...
...
@@ -2053,7 +2050,7 @@ static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
GetTickCount
(),
GetCurrentThreadId
(),
output
,
time
,
duration
,
flags
);
/* uncompressed samples are slightly out of order because of decoding delay */
ok
(
callback
->
last_pts
[
output
]
<=
time
,
"
got time %I64d
\n
"
,
time
);
ok
(
callback
->
last_pts
[
output
]
<=
time
,
"
expected %I64d <= %I64d
\n
"
,
callback
->
last_pts
[
output
]
,
time
);
callback
->
last_pts
[
output
]
=
time
;
callback
->
next_pts
[
output
]
=
time
+
duration
;
...
...
@@ -2134,7 +2131,7 @@ static HRESULT WINAPI callback_advanced_OnStreamSample(IWMReaderCallbackAdvanced
trace
(
"%lu: %04lx: IWMReaderCallbackAdvanced::OnStreamSample(stream %u, pts %I64u, duration %I64u, flags %#lx)
\n
"
,
GetTickCount
(),
GetCurrentThreadId
(),
stream_number
,
pts
,
duration
,
flags
);
ok
(
callback
->
last_pts
[
output
]
<=
pts
,
"
got pts %I64d
\n
"
,
pts
);
ok
(
callback
->
last_pts
[
output
]
<=
pts
,
"
expected %I64d <= %I64d
\n
"
,
callback
->
last_pts
[
output
]
,
pts
);
callback
->
last_pts
[
output
]
=
pts
;
callback
->
next_pts
[
output
]
=
pts
+
duration
;
...
...
@@ -2146,7 +2143,7 @@ static HRESULT WINAPI callback_advanced_OnStreamSample(IWMReaderCallbackAdvanced
else
{
ok
(
callback
->
callback_tid
==
GetCurrentThreadId
(),
"got wrong thread
\n
"
);
ok
(
callback
->
last_pts
[
1
-
output
]
<=
pts
,
"
got pts %I64d
\n
"
,
pts
);
ok
(
callback
->
last_pts
[
1
-
output
]
<=
pts
,
"
expected %I64d <= %I64d
\n
"
,
callback
->
last_pts
[
1
-
output
]
,
pts
);
}
if
(
!
callback
->
output_tid
[
output
])
...
...
@@ -2572,8 +2569,6 @@ static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, st
callback
->
last_pts
[
1
]
=
0
;
callback
->
next_pts
[
1
]
=
0
;
memset
(
callback
->
output_tid
,
0
,
sizeof
(
callback
->
output_tid
));
if
(
callback
->
stream
)
callback
->
stream
->
input_tid
=
0
;
check_async_set_output_setting
(
advanced
,
0
,
L"DedicatedDeliveryThread"
,
WMT_TYPE_BOOL
,
callback
->
dedicated_threads
,
S_OK
);
...
...
@@ -2709,6 +2704,17 @@ static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, st
todo_wine
ok
(
hr
==
E_UNEXPECTED
,
"Got hr %#lx.
\n
"
,
hr
);
/* FIXME: native can switch mode without rewinding, but Wine can't */
IWMReader_Stop
(
reader
);
wait_stopped_callback
(
callback
);
callback
->
last_pts
[
0
]
=
0
;
callback
->
next_pts
[
0
]
=
0
;
callback
->
last_pts
[
1
]
=
0
;
callback
->
next_pts
[
1
]
=
0
;
hr
=
IWMReader_Start
(
reader
,
0
,
0
,
1
.
0
f
,
(
void
*
)
0xfacade
);
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
wait_started_callback
(
callback
);
callback
->
expect_time
=
13460000
;
hr
=
IWMReaderAdvanced2_DeliverTime
(
advanced
,
13460000
);
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
...
...
@@ -2716,7 +2722,7 @@ static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, st
todo_wine
ok
(
callback
->
last_pts
[
0
]
==
13460000
,
"Got pts %I64d.
\n
"
,
callback
->
last_pts
[
0
]);
todo_wine
ok
(
callback
->
next_pts
[
0
]
==
139
3
0000
,
"Got pts %I64d.
\n
"
,
callback
->
next_pts
[
0
]);
ok
(
callback
->
next_pts
[
0
]
==
139
2
0000
,
"Got pts %I64d.
\n
"
,
callback
->
next_pts
[
0
]);
todo_wine
ok
(
callback
->
last_pts
[
1
]
==
13260000
,
"Got pts %I64d.
\n
"
,
callback
->
last_pts
[
1
]);
todo_wine
...
...
@@ -2729,6 +2735,16 @@ static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, st
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
hr
=
IWMReaderAdvanced2_SetReceiveStreamSamples
(
advanced
,
2
,
TRUE
);
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
IWMReader_Stop
(
reader
);
wait_stopped_callback
(
callback
);
callback
->
last_pts
[
0
]
=
0
;
callback
->
next_pts
[
0
]
=
0
;
callback
->
last_pts
[
1
]
=
0
;
callback
->
next_pts
[
1
]
=
0
;
hr
=
IWMReader_Start
(
reader
,
0
,
0
,
1
.
0
f
,
(
void
*
)
0xfacade
);
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
wait_started_callback
(
callback
);
}
callback
->
expect_time
=
test_wmv_duration
*
2
;
...
...
@@ -3233,7 +3249,6 @@ static void test_async_reader_streaming(void)
ok
(
callback
.
refcount
>
1
,
"Got refcount %ld.
\n
"
,
callback
.
refcount
);
wait_opened_callback
(
&
callback
);
stream
.
input_tid
=
0
;
/* FIXME: currently required as Wine calls IStream_Stat synchronously in OpenStream */
hr
=
IWMReaderAdvanced2_OpenStream
(
advanced
,
&
stream
.
IStream_iface
,
&
callback
.
IWMReaderCallback_iface
,
(
void
**
)
0xdeadbee0
);
ok
(
hr
==
E_UNEXPECTED
,
"Got hr %#lx.
\n
"
,
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