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
56043971
Commit
56043971
authored
Oct 25, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Nov 07, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dmime: Implement segment state chunked playback.
parent
63661495
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
107 additions
and
15 deletions
+107
-15
dmime_private.h
dlls/dmime/dmime_private.h
+3
-0
performance.c
dlls/dmime/performance.c
+58
-8
segmentstate.c
dlls/dmime/segmentstate.c
+46
-7
No files found.
dlls/dmime/dmime_private.h
View file @
56043971
...
...
@@ -75,12 +75,15 @@ extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSo
extern
HRESULT
segment_state_create
(
IDirectMusicSegment
*
segment
,
MUSIC_TIME
start_time
,
IDirectMusicPerformance8
*
performance
,
IDirectMusicSegmentState
**
ret_iface
);
extern
HRESULT
segment_state_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
);
extern
HRESULT
segment_state_tick
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
);
extern
HRESULT
segment_state_end_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
);
extern
HRESULT
wave_track_create_from_chunk
(
IStream
*
stream
,
struct
chunk_entry
*
parent
,
IDirectMusicTrack8
**
ret_iface
);
extern
HRESULT
performance_get_dsound
(
IDirectMusicPerformance8
*
iface
,
IDirectSound
**
dsound
);
extern
HRESULT
performance_send_segment_tick
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
);
extern
HRESULT
performance_send_segment_end
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
);
...
...
dlls/dmime/performance.c
View file @
56043971
...
...
@@ -28,6 +28,7 @@ enum dmus_internal_message_type
{
DMUS_PMSGT_INTERNAL_FIRST
=
0x10
,
DMUS_PMSGT_INTERNAL_SEGMENT_END
=
DMUS_PMSGT_INTERNAL_FIRST
,
DMUS_PMSGT_INTERNAL_SEGMENT_TICK
,
};
struct
pchannel_block
{
...
...
@@ -275,6 +276,43 @@ static inline struct performance *impl_from_IDirectMusicPerformance8(IDirectMusi
return
CONTAINING_RECORD
(
iface
,
struct
performance
,
IDirectMusicPerformance8_iface
);
}
static
HRESULT
performance_send_segment_start
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
HRESULT
hr
;
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_performance
,
GUID_NOTIFICATION_PERFORMANCE
,
DMUS_NOTIFICATION_MUSICSTARTED
,
NULL
)))
return
hr
;
if
(
FAILED
(
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_segment
,
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGSTART
,
(
IUnknown
*
)
state
)))
return
hr
;
if
(
FAILED
(
hr
=
performance_send_pmsg
(
This
,
music_time
,
DMUS_PMSGF_TOOL_IMMEDIATE
,
DMUS_PMSGT_DIRTY
,
NULL
)))
return
hr
;
return
S_OK
;
}
HRESULT
performance_send_segment_tick
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
REFERENCE_TIME
time
;
HRESULT
hr
;
if
(
FAILED
(
hr
=
IDirectMusicPerformance8_MusicToReferenceTime
(
iface
,
music_time
,
&
time
)))
return
hr
;
if
(
FAILED
(
hr
=
IDirectMusicPerformance8_ReferenceToMusicTime
(
iface
,
time
+
2000000
,
&
music_time
)))
return
hr
;
if
(
FAILED
(
hr
=
performance_send_pmsg
(
This
,
music_time
,
DMUS_PMSGF_TOOL_QUEUE
,
DMUS_PMSGT_INTERNAL_SEGMENT_TICK
,
(
IUnknown
*
)
state
)))
return
hr
;
return
S_OK
;
}
HRESULT
performance_send_segment_end
(
IDirectMusicPerformance8
*
iface
,
MUSIC_TIME
music_time
,
IDirectMusicSegmentState
*
state
)
{
...
...
@@ -1235,16 +1273,11 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface,
return
hr
;
}
EnterCriticalSection
(
&
This
->
safe
);
hr
=
IDirectMusicSegment_GetLength
(
segment
,
&
length
);
if
(
SUCCEEDED
(
hr
))
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_performance
,
GUID_NOTIFICATION_PERFORMANCE
,
DMUS_NOTIFICATION_MUSICSTARTED
,
NULL
);
if
(
SUCCEEDED
(
hr
))
hr
=
performance_send_notification_pmsg
(
This
,
music_time
,
This
->
notification_segment
,
GUID_NOTIFICATION_SEGMENT
,
DMUS_NOTIFICATION_SEGSTART
,
(
IUnknown
*
)
state
);
if
(
SUCCEEDED
(
hr
))
hr
=
performance_send_pmsg
(
This
,
music_time
,
DMUS_PMSGF_TOOL_IMMEDIATE
,
DMUS_PMSGT_DIRTY
,
NULL
);
hr
=
performance_send_segment_start
(
iface
,
music_time
,
state
);
if
(
SUCCEEDED
(
hr
))
hr
=
segment_state_play
(
state
,
iface
);
...
...
@@ -1266,6 +1299,8 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface,
IDirectMusicSegmentState_AddRef
(
state
);
}
LeaveCriticalSection
(
&
This
->
safe
);
IDirectMusicSegmentState_Release
(
state
);
IDirectMusicSegment_Release
(
segment
);
return
hr
;
...
...
@@ -1839,6 +1874,21 @@ static HRESULT WINAPI performance_tool_ProcessPMsg(IDirectMusicTool *iface,
WARN
(
"Failed to play wave buffer, hr %#lx
\n
"
,
hr
);
break
;
case
DMUS_PMSGT_INTERNAL_SEGMENT_TICK
:
msg
->
rtTime
+=
10000000
;
msg
->
dwFlags
&=
~
DMUS_PMSGF_MUSICTIME
;
/* re-send the tick message until segment_state_tick returns S_FALSE */
if
(
FAILED
(
hr
=
segment_state_tick
((
IDirectMusicSegmentState
*
)
msg
->
punkUser
,
(
IDirectMusicPerformance8
*
)
performance
)))
ERR
(
"Failed to tick segment state %p, hr %#lx
\n
"
,
msg
->
punkUser
,
hr
);
else
if
(
hr
==
S_FALSE
)
return
DMUS_S_FREE
;
/* done ticking */
else
if
(
FAILED
(
hr
=
IDirectMusicPerformance_SendPMsg
(
performance
,
msg
)))
ERR
(
"Failed to queue tick for segment state %p, hr %#lx
\n
"
,
msg
->
punkUser
,
hr
);
return
S_OK
;
case
DMUS_PMSGT_INTERNAL_SEGMENT_END
:
if
(
FAILED
(
hr
=
segment_state_end_play
((
IDirectMusicSegmentState
*
)
msg
->
punkUser
,
(
IDirectMusicPerformance8
*
)
performance
)))
...
...
dlls/dmime/segmentstate.c
View file @
56043971
...
...
@@ -51,6 +51,7 @@ struct segment_state
MUSIC_TIME
start_time
;
MUSIC_TIME
start_point
;
MUSIC_TIME
end_point
;
MUSIC_TIME
played
;
BOOL
auto_download
;
struct
list
tracks
;
...
...
@@ -271,25 +272,63 @@ HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME start_time
return
hr
;
}
HRESULT
segment_state_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
)
static
HRESULT
segment_state_play_chunk
(
struct
segment_state
*
This
,
IDirectMusicPerformance8
*
performance
,
REFERENCE_TIME
duration
,
DWORD
track_flags
)
{
struct
segment_state
*
This
=
impl_from_IDirectMusicSegmentState8
((
IDirectMusicSegmentState8
*
)
iface
);
DWORD
track_flags
=
DMUS_TRACKF_DIRTY
|
DMUS_TRACKF_START
|
DMUS_TRACKF_SEEK
;
MUSIC_TIME
start_time
=
This
->
start_point
,
end_time
=
This
->
end_point
;
IDirectMusicSegmentState
*
iface
=
(
IDirectMusicSegmentState
*
)
&
This
->
IDirectMusicSegmentState8_iface
;
MUSIC_TIME
next_time
,
played
;
struct
track_entry
*
entry
;
REFERENCE_TIME
time
;
HRESULT
hr
=
S_OK
;
if
(
FAILED
(
hr
=
IDirectMusicPerformance8_MusicToReferenceTime
(
performance
,
This
->
start_time
+
This
->
played
,
&
time
)))
return
hr
;
if
(
FAILED
(
hr
=
IDirectMusicPerformance8_ReferenceToMusicTime
(
performance
,
time
+
duration
,
&
next_time
)))
return
hr
;
played
=
min
(
next_time
-
This
->
start_time
,
This
->
end_point
-
This
->
start_point
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
This
->
tracks
,
struct
track_entry
,
entry
)
{
if
(
FAILED
(
hr
=
IDirectMusicTrack_Play
(
entry
->
track
,
entry
->
state_data
,
start_time
,
end_time
,
This
->
start_time
,
track_flags
,
(
IDirectMusicPerformance
*
)
performance
,
iface
,
entry
->
track_id
)))
if
(
FAILED
(
hr
=
IDirectMusicTrack_Play
(
entry
->
track
,
entry
->
state_data
,
This
->
start_point
+
This
->
played
,
This
->
start_point
+
played
,
This
->
start_time
,
track_flags
,
(
IDirectMusicPerformance
*
)
performance
,
iface
,
entry
->
track_id
)))
{
WARN
(
"Failed to play track %p, hr %#lx
\n
"
,
entry
->
track
,
hr
);
break
;
}
}
return
hr
;
This
->
played
=
played
;
if
(
This
->
start_point
+
This
->
played
>=
This
->
end_point
)
return
S_FALSE
;
return
S_OK
;
}
HRESULT
segment_state_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
)
{
struct
segment_state
*
This
=
impl_from_IDirectMusicSegmentState8
((
IDirectMusicSegmentState8
*
)
iface
);
HRESULT
hr
;
TRACE
(
"%p %p
\n
"
,
iface
,
performance
);
if
(
FAILED
(
hr
=
segment_state_play_chunk
(
This
,
performance
,
10000000
,
DMUS_TRACKF_START
|
DMUS_TRACKF_SEEK
|
DMUS_TRACKF_DIRTY
)))
return
hr
;
if
(
hr
==
S_FALSE
)
return
S_OK
;
return
performance_send_segment_tick
(
performance
,
This
->
start_time
,
iface
);
}
HRESULT
segment_state_tick
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
)
{
struct
segment_state
*
This
=
impl_from_IDirectMusicSegmentState8
((
IDirectMusicSegmentState8
*
)
iface
);
TRACE
(
"%p %p
\n
"
,
iface
,
performance
);
return
segment_state_play_chunk
(
This
,
performance
,
10000000
,
0
);
}
HRESULT
segment_state_end_play
(
IDirectMusicSegmentState
*
iface
,
IDirectMusicPerformance8
*
performance
)
...
...
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