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
8697c6c0
Commit
8697c6c0
authored
Feb 18, 2021
by
Zebediah Figura
Committed by
Alexandre Julliard
Feb 19, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Explicitly translate the channel mask.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b44d3a39
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
129 additions
and
16 deletions
+129
-16
gst_private.h
dlls/winegstreamer/gst_private.h
+1
-0
gstdemux.c
dlls/winegstreamer/gstdemux.c
+20
-15
wg_parser.c
dlls/winegstreamer/wg_parser.c
+108
-1
No files found.
dlls/winegstreamer/gst_private.h
View file @
8697c6c0
...
...
@@ -128,6 +128,7 @@ struct wg_format
}
format
;
uint32_t
channels
;
uint32_t
channel_mask
;
/* In WinMM format. */
uint32_t
rate
;
}
audio
;
}
u
;
...
...
dlls/winegstreamer/gstdemux.c
View file @
8697c6c0
...
...
@@ -102,20 +102,6 @@ static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface);
static
HRESULT
WINAPI
GST_ChangeStop
(
IMediaSeeking
*
iface
);
static
HRESULT
WINAPI
GST_ChangeRate
(
IMediaSeeking
*
iface
);
static
DWORD
channel_mask_from_count
(
uint32_t
count
)
{
switch
(
count
)
{
case
1
:
return
KSAUDIO_SPEAKER_MONO
;
case
2
:
return
KSAUDIO_SPEAKER_STEREO
;
case
4
:
return
KSAUDIO_SPEAKER_SURROUND
;
case
5
:
return
KSAUDIO_SPEAKER_5POINT1
&
~
SPEAKER_LOW_FREQUENCY
;
case
6
:
return
KSAUDIO_SPEAKER_5POINT1
;
case
8
:
return
KSAUDIO_SPEAKER_7POINT1
;
default:
return
0
;
}
}
static
bool
amt_from_wg_format_audio
(
AM_MEDIA_TYPE
*
mt
,
const
struct
wg_format
*
format
)
{
mt
->
majortype
=
MEDIATYPE_Audio
;
...
...
@@ -220,7 +206,7 @@ static bool amt_from_wg_format_audio(AM_MEDIA_TYPE *mt, const struct wg_format *
wave_format
->
Format
.
wBitsPerSample
=
depth
;
wave_format
->
Format
.
cbSize
=
sizeof
(
*
wave_format
)
-
sizeof
(
WAVEFORMATEX
);
wave_format
->
Samples
.
wValidBitsPerSample
=
depth
;
wave_format
->
dwChannelMask
=
channel_mask_from_count
(
format
->
u
.
audio
.
channels
)
;
wave_format
->
dwChannelMask
=
format
->
u
.
audio
.
channel_mask
;
wave_format
->
SubFormat
=
is_float
?
KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
:
KSDATAFORMAT_SUBTYPE_PCM
;
mt
->
lSampleSize
=
wave_format
->
Format
.
nBlockAlign
;
}
...
...
@@ -423,6 +409,25 @@ static bool amt_to_wg_format_audio(const AM_MEDIA_TYPE *mt, struct wg_format *fo
format
->
u
.
audio
.
channels
=
audio_format
->
nChannels
;
format
->
u
.
audio
.
rate
=
audio_format
->
nSamplesPerSec
;
if
(
audio_format
->
wFormatTag
==
WAVE_FORMAT_EXTENSIBLE
)
{
const
WAVEFORMATEXTENSIBLE
*
ext_format
=
(
const
WAVEFORMATEXTENSIBLE
*
)
mt
->
pbFormat
;
format
->
u
.
audio
.
channel_mask
=
ext_format
->
dwChannelMask
;
}
else
{
if
(
audio_format
->
nChannels
==
1
)
format
->
u
.
audio
.
channel_mask
=
KSAUDIO_SPEAKER_MONO
;
else
if
(
audio_format
->
nChannels
==
2
)
format
->
u
.
audio
.
channel_mask
=
KSAUDIO_SPEAKER_STEREO
;
else
{
ERR
(
"Unexpected channel count %u.
\n
"
,
audio_format
->
nChannels
);
return
false
;
}
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
format_map
);
++
i
)
{
if
(
IsEqualGUID
(
&
mt
->
subtype
,
format_map
[
i
].
subtype
)
...
...
dlls/winegstreamer/wg_parser.c
View file @
8697c6c0
...
...
@@ -109,11 +109,70 @@ static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format)
}
}
static
uint32_t
wg_channel_position_from_gst
(
GstAudioChannelPosition
position
)
{
static
const
uint32_t
position_map
[]
=
{
SPEAKER_FRONT_LEFT
,
SPEAKER_FRONT_RIGHT
,
SPEAKER_FRONT_CENTER
,
SPEAKER_LOW_FREQUENCY
,
SPEAKER_BACK_LEFT
,
SPEAKER_BACK_RIGHT
,
SPEAKER_FRONT_LEFT_OF_CENTER
,
SPEAKER_FRONT_RIGHT_OF_CENTER
,
SPEAKER_BACK_CENTER
,
0
,
SPEAKER_SIDE_LEFT
,
SPEAKER_SIDE_RIGHT
,
SPEAKER_TOP_FRONT_LEFT
,
SPEAKER_TOP_FRONT_RIGHT
,
SPEAKER_TOP_FRONT_CENTER
,
SPEAKER_TOP_CENTER
,
SPEAKER_TOP_BACK_LEFT
,
SPEAKER_TOP_BACK_RIGHT
,
0
,
0
,
SPEAKER_TOP_BACK_CENTER
,
};
if
(
position
<
ARRAY_SIZE
(
position_map
))
return
position_map
[
position
];
return
0
;
}
static
uint32_t
wg_channel_mask_from_gst
(
const
GstAudioInfo
*
info
)
{
uint32_t
mask
=
0
,
position
;
unsigned
int
i
;
for
(
i
=
0
;
i
<
GST_AUDIO_INFO_CHANNELS
(
info
);
++
i
)
{
if
(
!
(
position
=
wg_channel_position_from_gst
(
GST_AUDIO_INFO_POSITION
(
info
,
i
))))
{
GST_WARNING
(
"Unsupported channel %#x."
,
GST_AUDIO_INFO_POSITION
(
info
,
i
));
return
0
;
}
/* Make sure it's also in WinMM order. WinMM mandates that channels be
* ordered, as it were, from least to most significant SPEAKER_* bit.
* Hence we fail if the current channel was already specified, or if any
* higher bit was already specified. */
if
(
mask
&
~
(
position
-
1
))
{
GST_WARNING
(
"Unsupported channel order."
);
return
0
;
}
mask
|=
position
;
}
return
mask
;
}
static
void
wg_format_from_audio_info
(
struct
wg_format
*
format
,
const
GstAudioInfo
*
info
)
{
format
->
major_type
=
WG_MAJOR_TYPE_AUDIO
;
format
->
u
.
audio
.
format
=
wg_audio_format_from_gst
(
GST_AUDIO_INFO_FORMAT
(
info
));
format
->
u
.
audio
.
channels
=
GST_AUDIO_INFO_CHANNELS
(
info
);
format
->
u
.
audio
.
channel_mask
=
wg_channel_mask_from_gst
(
info
);
format
->
u
.
audio
.
rate
=
GST_AUDIO_INFO_RATE
(
info
);
}
...
...
@@ -273,15 +332,63 @@ static GstAudioFormat wg_audio_format_to_gst(enum wg_audio_format format)
}
}
static
void
wg_channel_mask_to_gst
(
GstAudioChannelPosition
*
positions
,
uint32_t
mask
,
uint32_t
channel_count
)
{
const
uint32_t
orig_mask
=
mask
;
unsigned
int
i
;
DWORD
bit
;
static
const
GstAudioChannelPosition
position_map
[]
=
{
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER
,
GST_AUDIO_CHANNEL_POSITION_LFE1
,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT
,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
,
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER
,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT
,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
,
GST_AUDIO_CHANNEL_POSITION_TOP_CENTER
,
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT
,
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER
,
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT
,
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT
,
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER
,
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT
,
};
for
(
i
=
0
;
i
<
channel_count
;
++
i
)
{
positions
[
i
]
=
GST_AUDIO_CHANNEL_POSITION_NONE
;
if
(
BitScanForward
(
&
bit
,
mask
))
{
if
(
bit
<
ARRAY_SIZE
(
position_map
))
positions
[
i
]
=
position_map
[
bit
];
else
GST_WARNING
(
"Invalid channel mask %#x.
\n
"
,
orig_mask
);
mask
&=
~
(
1
<<
bit
);
}
else
{
GST_WARNING
(
"Incomplete channel mask %#x.
\n
"
,
orig_mask
);
}
}
}
static
GstCaps
*
wg_format_to_caps_audio
(
const
struct
wg_format
*
format
)
{
GstAudioChannelPosition
positions
[
32
];
GstAudioFormat
audio_format
;
GstAudioInfo
info
;
if
((
audio_format
=
wg_audio_format_to_gst
(
format
->
u
.
audio
.
format
))
==
GST_AUDIO_FORMAT_UNKNOWN
)
return
NULL
;
gst_audio_info_set_format
(
&
info
,
audio_format
,
format
->
u
.
audio
.
rate
,
format
->
u
.
audio
.
channels
,
NULL
);
wg_channel_mask_to_gst
(
positions
,
format
->
u
.
audio
.
channel_mask
,
format
->
u
.
audio
.
channels
);
gst_audio_info_set_format
(
&
info
,
audio_format
,
format
->
u
.
audio
.
rate
,
format
->
u
.
audio
.
channels
,
positions
);
return
gst_audio_info_to_caps
(
&
info
);
}
...
...
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