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
d33cb57e
Commit
d33cb57e
authored
Jun 13, 2022
by
Rémi Bernon
Committed by
Alexandre Julliard
Jun 16, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Implement ResamplerMediaObject transform.
Signed-off-by:
Rémi Bernon
<
rbernon@codeweavers.com
>
parent
b6a7a021
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
376 additions
and
66 deletions
+376
-66
mf.c
dlls/mf/tests/mf.c
+0
-39
resampler.c
dlls/winegstreamer/resampler.c
+375
-27
wg_transform.c
dlls/winegstreamer/wg_transform.c
+1
-0
No files found.
dlls/mf/tests/mf.c
View file @
d33cb57e
...
...
@@ -7570,10 +7570,8 @@ static void test_audio_convert(void)
/* check default media types */
hr
=
IMFTransform_GetInputStreamInfo
(
transform
,
0
,
&
input_info
);
todo_wine
ok
(
hr
==
MF_E_TRANSFORM_TYPE_NOT_SET
,
"GetInputStreamInfo returned %#lx
\n
"
,
hr
);
hr
=
IMFTransform_GetOutputStreamInfo
(
transform
,
0
,
&
output_info
);
todo_wine
ok
(
hr
==
MF_E_TRANSFORM_TYPE_NOT_SET
,
"GetOutputStreamInfo returned %#lx
\n
"
,
hr
);
i
=
-
1
;
...
...
@@ -7586,9 +7584,7 @@ static void test_audio_convert(void)
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
winetest_pop_context
();
}
todo_wine
ok
(
hr
==
MF_E_NO_MORE_TYPES
,
"GetOutputAvailableType returned %#lx
\n
"
,
hr
);
todo_wine
ok
(
i
==
4
,
"%lu output media types
\n
"
,
i
);
i
=
-
1
;
...
...
@@ -7603,9 +7599,7 @@ static void test_audio_convert(void)
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
winetest_pop_context
();
}
todo_wine
ok
(
hr
==
MF_E_NO_MORE_TYPES
,
"GetInputAvailableType returned %#lx
\n
"
,
hr
);
todo_wine
ok
(
i
==
2
,
"%lu input media types
\n
"
,
i
);
/* setting output media type first doesn't work */
...
...
@@ -7614,7 +7608,6 @@ static void test_audio_convert(void)
ok
(
hr
==
S_OK
,
"MFCreateMediaType returned %#lx
\n
"
,
hr
);
init_media_type
(
media_type
,
output_type_desc
,
-
1
);
hr
=
IMFTransform_SetOutputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
MF_E_TRANSFORM_TYPE_NOT_SET
,
"SetOutputType returned %#lx.
\n
"
,
hr
);
ret
=
IMFMediaType_Release
(
media_type
);
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
...
...
@@ -7624,31 +7617,25 @@ static void test_audio_convert(void)
hr
=
MFCreateMediaType
(
&
media_type
);
ok
(
hr
==
S_OK
,
"MFCreateMediaType returned %#lx
\n
"
,
hr
);
hr
=
IMFTransform_SetInputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
MF_E_ATTRIBUTENOTFOUND
,
"SetInputType returned %#lx.
\n
"
,
hr
);
init_media_type
(
media_type
,
input_type_desc
,
1
);
hr
=
IMFTransform_SetInputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
MF_E_ATTRIBUTENOTFOUND
,
"SetInputType returned %#lx.
\n
"
,
hr
);
init_media_type
(
media_type
,
input_type_desc
,
2
);
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
input_type_desc
)
-
1
;
++
i
)
{
hr
=
IMFTransform_SetInputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
MF_E_INVALIDMEDIATYPE
,
"SetInputType returned %#lx.
\n
"
,
hr
);
init_media_type
(
media_type
,
input_type_desc
,
i
+
1
);
}
hr
=
IMFTransform_SetInputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"SetInputType returned %#lx.
\n
"
,
hr
);
ret
=
IMFMediaType_Release
(
media_type
);
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
hr
=
IMFTransform_GetInputStreamInfo
(
transform
,
0
,
&
input_info
);
todo_wine
ok
(
hr
==
MF_E_TRANSFORM_TYPE_NOT_SET
,
"GetInputStreamInfo returned %#lx
\n
"
,
hr
);
hr
=
IMFTransform_GetOutputStreamInfo
(
transform
,
0
,
&
output_info
);
todo_wine
ok
(
hr
==
MF_E_TRANSFORM_TYPE_NOT_SET
,
"GetOutputStreamInfo returned %#lx
\n
"
,
hr
);
/* check new output media types */
...
...
@@ -7663,9 +7650,7 @@ static void test_audio_convert(void)
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
winetest_pop_context
();
}
todo_wine
ok
(
hr
==
MF_E_NO_MORE_TYPES
,
"GetOutputAvailableType returned %#lx
\n
"
,
hr
);
todo_wine
ok
(
i
==
4
,
"%lu output media types
\n
"
,
i
);
/* check required output media type attributes */
...
...
@@ -7673,50 +7658,36 @@ static void test_audio_convert(void)
hr
=
MFCreateMediaType
(
&
media_type
);
ok
(
hr
==
S_OK
,
"MFCreateMediaType returned %#lx
\n
"
,
hr
);
hr
=
IMFTransform_SetOutputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
MF_E_ATTRIBUTENOTFOUND
,
"SetOutputType returned %#lx.
\n
"
,
hr
);
init_media_type
(
media_type
,
output_type_desc
,
1
);
hr
=
IMFTransform_SetOutputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
MF_E_ATTRIBUTENOTFOUND
,
"SetOutputType returned %#lx.
\n
"
,
hr
);
init_media_type
(
media_type
,
output_type_desc
,
2
);
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
output_type_desc
)
-
1
;
++
i
)
{
hr
=
IMFTransform_SetOutputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
MF_E_INVALIDMEDIATYPE
,
"SetOutputType returned %#lx.
\n
"
,
hr
);
init_media_type
(
media_type
,
output_type_desc
,
i
+
1
);
}
hr
=
IMFTransform_SetOutputType
(
transform
,
0
,
media_type
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"SetOutputType returned %#lx.
\n
"
,
hr
);
ret
=
IMFMediaType_Release
(
media_type
);
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
memset
(
&
input_info
,
0xcd
,
sizeof
(
input_info
));
hr
=
IMFTransform_GetInputStreamInfo
(
transform
,
0
,
&
input_info
);
todo_wine
ok
(
hr
==
S_OK
,
"GetInputStreamInfo returned %#lx
\n
"
,
hr
);
todo_wine
ok
(
input_info
.
hnsMaxLatency
==
0
,
"got hnsMaxLatency %s
\n
"
,
wine_dbgstr_longlong
(
input_info
.
hnsMaxLatency
));
todo_wine
ok
(
input_info
.
dwFlags
==
0
,
"got dwFlags %#lx
\n
"
,
input_info
.
dwFlags
);
todo_wine
ok
(
input_info
.
cbSize
==
8
,
"got cbSize %lu
\n
"
,
input_info
.
cbSize
);
todo_wine
ok
(
input_info
.
cbMaxLookahead
==
0
,
"got cbMaxLookahead %#lx
\n
"
,
input_info
.
cbMaxLookahead
);
todo_wine
ok
(
input_info
.
cbAlignment
==
1
,
"got cbAlignment %#lx
\n
"
,
input_info
.
cbAlignment
);
memset
(
&
output_info
,
0xcd
,
sizeof
(
output_info
));
hr
=
IMFTransform_GetOutputStreamInfo
(
transform
,
0
,
&
output_info
);
todo_wine
ok
(
hr
==
S_OK
,
"GetOutputStreamInfo returned %#lx
\n
"
,
hr
);
todo_wine
ok
(
output_info
.
dwFlags
==
0
,
"got dwFlags %#lx
\n
"
,
output_info
.
dwFlags
);
todo_wine
ok
(
output_info
.
cbSize
==
4
,
"got cbSize %#lx
\n
"
,
output_info
.
cbSize
);
todo_wine
ok
(
output_info
.
cbAlignment
==
1
,
"got cbAlignment %#lx
\n
"
,
output_info
.
cbAlignment
);
resource
=
FindResourceW
(
NULL
,
L"audiodata.bin"
,
(
const
WCHAR
*
)
RT_RCDATA
);
...
...
@@ -7731,13 +7702,10 @@ static void test_audio_convert(void)
hr
=
IMFSample_SetSampleDuration
(
sample
,
10000000
);
ok
(
hr
==
S_OK
,
"SetSampleDuration returned %#lx
\n
"
,
hr
);
hr
=
IMFTransform_ProcessInput
(
transform
,
0
,
sample
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"ProcessInput returned %#lx
\n
"
,
hr
);
hr
=
IMFTransform_ProcessMessage
(
transform
,
MFT_MESSAGE_COMMAND_DRAIN
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"ProcessMessage returned %#lx
\n
"
,
hr
);
hr
=
IMFTransform_ProcessInput
(
transform
,
0
,
sample
,
0
);
todo_wine
ok
(
hr
==
MF_E_NOTACCEPTING
,
"ProcessInput returned %#lx
\n
"
,
hr
);
IMFSample_Release
(
sample
);
...
...
@@ -7793,12 +7761,9 @@ static void test_audio_convert(void)
}
hr
=
IMFSample_GetSampleTime
(
sample
,
&
time
);
todo_wine
ok
(
hr
==
S_OK
,
"GetSampleTime returned %#lx
\n
"
,
hr
);
todo_wine_if
(
i
!=
0
)
ok
(
time
==
i
*
928798
,
"got time %I64d
\n
"
,
time
);
hr
=
IMFSample_GetSampleDuration
(
sample
,
&
duration
);
todo_wine
ok
(
hr
==
S_OK
,
"GetSampleDuration returned %#lx
\n
"
,
hr
);
todo_wine
ok
(
duration
==
897506
,
"got duration %I64d
\n
"
,
duration
);
...
...
@@ -7806,7 +7771,6 @@ static void test_audio_convert(void)
ok
(
hr
==
S_OK
,
"GetTotalLength returned %#lx
\n
"
,
hr
);
todo_wine
ok
(
length
==
15832
,
"got length %lu
\n
"
,
length
);
todo_wine
ok
(
audioconv_data_len
==
16084
,
"got remaining length %lu
\n
"
,
audioconv_data_len
);
check_sample_pcm16
(
sample
,
audioconv_data
,
output_file
,
FALSE
);
audioconv_data_len
-=
length
;
...
...
@@ -7821,7 +7785,6 @@ static void test_audio_convert(void)
todo_wine
ok
(
output
.
dwStatus
==
MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
||
broken
(
output
.
dwStatus
==
0
)
/* win7 */
,
"got dwStatus %#lx
\n
"
,
output
.
dwStatus
);
todo_wine
ok
(
status
==
0
,
"got status %#lx
\n
"
,
status
);
if
(
hr
==
S_OK
)
...
...
@@ -7853,11 +7816,9 @@ static void test_audio_convert(void)
memset
(
&
output
,
0
,
sizeof
(
output
));
output
.
pSample
=
sample
;
hr
=
IMFTransform_ProcessOutput
(
transform
,
0
,
1
,
&
output
,
&
status
);
todo_wine
ok
(
hr
==
MF_E_TRANSFORM_NEED_MORE_INPUT
,
"ProcessOutput returned %#lx
\n
"
,
hr
);
ok
(
output
.
pSample
==
sample
,
"got pSample %p
\n
"
,
output
.
pSample
);
ok
(
output
.
dwStatus
==
0
,
"got dwStatus %#lx
\n
"
,
output
.
dwStatus
);
todo_wine
ok
(
status
==
0
,
"got status %#lx
\n
"
,
status
);
hr
=
IMFSample_GetTotalLength
(
sample
,
&
length
);
ok
(
hr
==
S_OK
,
"GetTotalLength returned %#lx
\n
"
,
hr
);
...
...
dlls/winegstreamer/resampler.c
View file @
d33cb57e
...
...
@@ -28,6 +28,12 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
mfplat
);
WINE_DECLARE_DEBUG_CHANNEL
(
winediag
);
static
const
GUID
*
audio_formats
[]
=
{
&
MFAudioFormat_Float
,
&
MFAudioFormat_PCM
,
};
struct
resampler
{
IUnknown
IUnknown_inner
;
...
...
@@ -37,8 +43,35 @@ struct resampler
IPropertyStore
IPropertyStore_iface
;
IUnknown
*
outer
;
LONG
refcount
;
IMFMediaType
*
input_type
;
IMFMediaType
*
output_type
;
struct
wg_transform
*
wg_transform
;
struct
wg_sample_queue
*
wg_sample_queue
;
};
static
HRESULT
try_create_wg_transform
(
struct
resampler
*
impl
)
{
struct
wg_format
input_format
,
output_format
;
if
(
impl
->
wg_transform
)
wg_transform_destroy
(
impl
->
wg_transform
);
impl
->
wg_transform
=
NULL
;
mf_media_type_to_wg_format
(
impl
->
input_type
,
&
input_format
);
if
(
input_format
.
major_type
==
WG_MAJOR_TYPE_UNKNOWN
)
return
MF_E_INVALIDMEDIATYPE
;
mf_media_type_to_wg_format
(
impl
->
output_type
,
&
output_format
);
if
(
output_format
.
major_type
==
WG_MAJOR_TYPE_UNKNOWN
)
return
MF_E_INVALIDMEDIATYPE
;
if
(
!
(
impl
->
wg_transform
=
wg_transform_create
(
&
input_format
,
&
output_format
)))
return
E_FAIL
;
return
S_OK
;
}
static
inline
struct
resampler
*
impl_from_IUnknown
(
IUnknown
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
resampler
,
IUnknown_inner
);
...
...
@@ -89,7 +122,17 @@ static ULONG WINAPI unknown_Release(IUnknown *iface)
TRACE
(
"iface %p decreasing refcount to %lu.
\n
"
,
iface
,
refcount
);
if
(
!
refcount
)
{
if
(
impl
->
wg_transform
)
wg_transform_destroy
(
impl
->
wg_transform
);
if
(
impl
->
input_type
)
IMFMediaType_Release
(
impl
->
input_type
);
if
(
impl
->
output_type
)
IMFMediaType_Release
(
impl
->
output_type
);
wg_sample_queue_destroy
(
impl
->
wg_sample_queue
);
free
(
impl
);
}
return
refcount
;
}
...
...
@@ -124,15 +167,17 @@ static ULONG WINAPI transform_Release(IMFTransform *iface)
static
HRESULT
WINAPI
transform_GetStreamLimits
(
IMFTransform
*
iface
,
DWORD
*
input_minimum
,
DWORD
*
input_maximum
,
DWORD
*
output_minimum
,
DWORD
*
output_maximum
)
{
FIXME
(
"iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p stub!
\n
"
,
TRACE
(
"iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p.
\n
"
,
iface
,
input_minimum
,
input_maximum
,
output_minimum
,
output_maximum
);
return
E_NOTIMPL
;
*
input_minimum
=
*
input_maximum
=
*
output_minimum
=
*
output_maximum
=
1
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_GetStreamCount
(
IMFTransform
*
iface
,
DWORD
*
inputs
,
DWORD
*
outputs
)
{
FIXME
(
"iface %p, inputs %p, outputs %p stub!
\n
"
,
iface
,
inputs
,
outputs
);
return
E_NOTIMPL
;
TRACE
(
"iface %p, inputs %p, outputs %p.
\n
"
,
iface
,
inputs
,
outputs
);
*
inputs
=
*
outputs
=
1
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_GetStreamIDs
(
IMFTransform
*
iface
,
DWORD
input_size
,
DWORD
*
inputs
,
...
...
@@ -145,14 +190,46 @@ static HRESULT WINAPI transform_GetStreamIDs(IMFTransform *iface, DWORD input_si
static
HRESULT
WINAPI
transform_GetInputStreamInfo
(
IMFTransform
*
iface
,
DWORD
id
,
MFT_INPUT_STREAM_INFO
*
info
)
{
FIXME
(
"iface %p, id %#lx, info %p stub!
\n
"
,
iface
,
id
,
info
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
UINT32
block_alignment
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, info %p.
\n
"
,
iface
,
id
,
info
);
if
(
!
impl
->
input_type
||
!
impl
->
output_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
IMFMediaType_GetUINT32
(
impl
->
input_type
,
&
MF_MT_AUDIO_BLOCK_ALIGNMENT
,
&
block_alignment
)))
return
hr
;
info
->
dwFlags
=
0
;
info
->
cbSize
=
block_alignment
;
info
->
cbAlignment
=
1
;
info
->
hnsMaxLatency
=
0
;
info
->
cbMaxLookahead
=
0
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_GetOutputStreamInfo
(
IMFTransform
*
iface
,
DWORD
id
,
MFT_OUTPUT_STREAM_INFO
*
info
)
{
FIXME
(
"iface %p, id %#lx, info %p stub!
\n
"
,
iface
,
id
,
info
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
UINT32
block_alignment
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, info %p.
\n
"
,
iface
,
id
,
info
);
if
(
!
impl
->
input_type
||
!
impl
->
output_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
IMFMediaType_GetUINT32
(
impl
->
output_type
,
&
MF_MT_AUDIO_BLOCK_ALIGNMENT
,
&
block_alignment
)))
return
hr
;
info
->
dwFlags
=
0
;
info
->
cbSize
=
block_alignment
;
info
->
cbAlignment
=
1
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_GetAttributes
(
IMFTransform
*
iface
,
IMFAttributes
**
attributes
)
...
...
@@ -185,42 +262,214 @@ static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD strea
return
E_NOTIMPL
;
}
static
HRESULT
get_available_media_type
(
DWORD
index
,
IMFMediaType
**
type
,
BOOL
output
)
{
UINT32
sample_size
,
sample_rate
=
48000
,
block_alignment
,
channel_count
=
2
;
IMFMediaType
*
media_type
;
const
GUID
*
subtype
;
HRESULT
hr
;
if
(
FAILED
(
hr
=
MFCreateMediaType
(
&
media_type
)))
return
hr
;
*
type
=
NULL
;
if
(
index
>=
(
output
?
2
:
1
)
*
ARRAY_SIZE
(
audio_formats
))
return
MF_E_NO_MORE_TYPES
;
subtype
=
audio_formats
[
index
%
ARRAY_SIZE
(
audio_formats
)];
if
(
FAILED
(
hr
=
IMFMediaType_SetGUID
(
media_type
,
&
MF_MT_MAJOR_TYPE
,
&
MFMediaType_Audio
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetGUID
(
media_type
,
&
MF_MT_SUBTYPE
,
subtype
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_ALL_SAMPLES_INDEPENDENT
,
1
)))
goto
done
;
if
(
index
<
ARRAY_SIZE
(
audio_formats
))
goto
done
;
if
(
IsEqualGUID
(
subtype
,
&
MFAudioFormat_Float
))
sample_size
=
32
;
else
if
(
IsEqualGUID
(
subtype
,
&
MFAudioFormat_PCM
))
sample_size
=
16
;
else
{
FIXME
(
"Subtype %s not implemented!
\n
"
,
debugstr_guid
(
subtype
));
hr
=
E_NOTIMPL
;
goto
done
;
}
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_BITS_PER_SAMPLE
,
sample_size
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_NUM_CHANNELS
,
channel_count
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_SAMPLES_PER_SECOND
,
sample_rate
)))
goto
done
;
block_alignment
=
sample_size
*
channel_count
/
8
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_BLOCK_ALIGNMENT
,
block_alignment
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_AVG_BYTES_PER_SECOND
,
sample_rate
*
block_alignment
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_PREFER_WAVEFORMATEX
,
1
)))
goto
done
;
done:
if
(
SUCCEEDED
(
hr
))
IMFMediaType_AddRef
((
*
type
=
media_type
));
IMFMediaType_Release
(
media_type
);
return
hr
;
}
static
HRESULT
WINAPI
transform_GetInputAvailableType
(
IMFTransform
*
iface
,
DWORD
id
,
DWORD
index
,
IMFMediaType
**
type
)
{
FIXME
(
"iface %p, id %#lx, index %lu, type %p stub!
\n
"
,
iface
,
id
,
index
,
type
);
return
E_NOTIMPL
;
TRACE
(
"iface %p, id %#lx, index %#lx, type %p.
\n
"
,
iface
,
id
,
index
,
type
);
return
get_available_media_type
(
index
,
type
,
FALSE
)
;
}
static
HRESULT
WINAPI
transform_GetOutputAvailableType
(
IMFTransform
*
iface
,
DWORD
id
,
DWORD
index
,
IMFMediaType
**
type
)
{
FIXME
(
"iface %p, id %#lx, index %lu, type %p stub!
\n
"
,
iface
,
id
,
index
,
type
);
return
E_NOTIMPL
;
TRACE
(
"iface %p, id %#lx, index %#lx, type %p.
\n
"
,
iface
,
id
,
index
,
type
);
return
get_available_media_type
(
index
,
type
,
TRUE
);
}
static
HRESULT
check_media_type
(
IMFMediaType
*
type
)
{
MF_ATTRIBUTE_TYPE
item_type
;
GUID
major
,
subtype
;
HRESULT
hr
;
ULONG
i
;
if
(
FAILED
(
hr
=
IMFMediaType_GetGUID
(
type
,
&
MF_MT_MAJOR_TYPE
,
&
major
))
||
FAILED
(
hr
=
IMFMediaType_GetGUID
(
type
,
&
MF_MT_SUBTYPE
,
&
subtype
)))
return
MF_E_ATTRIBUTENOTFOUND
;
if
(
!
IsEqualGUID
(
&
major
,
&
MFMediaType_Audio
))
return
MF_E_INVALIDMEDIATYPE
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
audio_formats
);
++
i
)
if
(
IsEqualGUID
(
&
subtype
,
audio_formats
[
i
]))
break
;
if
(
i
==
ARRAY_SIZE
(
audio_formats
))
return
MF_E_INVALIDMEDIATYPE
;
if
(
FAILED
(
IMFMediaType_GetItemType
(
type
,
&
MF_MT_AUDIO_BITS_PER_SAMPLE
,
&
item_type
))
||
item_type
!=
MF_ATTRIBUTE_UINT32
)
return
MF_E_INVALIDMEDIATYPE
;
if
(
FAILED
(
IMFMediaType_GetItemType
(
type
,
&
MF_MT_AUDIO_AVG_BYTES_PER_SECOND
,
&
item_type
))
||
item_type
!=
MF_ATTRIBUTE_UINT32
)
return
MF_E_INVALIDMEDIATYPE
;
if
(
FAILED
(
IMFMediaType_GetItemType
(
type
,
&
MF_MT_AUDIO_NUM_CHANNELS
,
&
item_type
))
||
item_type
!=
MF_ATTRIBUTE_UINT32
)
return
MF_E_INVALIDMEDIATYPE
;
if
(
FAILED
(
IMFMediaType_GetItemType
(
type
,
&
MF_MT_AUDIO_SAMPLES_PER_SECOND
,
&
item_type
))
||
item_type
!=
MF_ATTRIBUTE_UINT32
)
return
MF_E_INVALIDMEDIATYPE
;
if
(
FAILED
(
IMFMediaType_GetItemType
(
type
,
&
MF_MT_AUDIO_BLOCK_ALIGNMENT
,
&
item_type
))
||
item_type
!=
MF_ATTRIBUTE_UINT32
)
return
MF_E_INVALIDMEDIATYPE
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_SetInputType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
*
type
,
DWORD
flags
)
{
FIXME
(
"iface %p, id %#lx, type %p, flags %#lx stub!
\n
"
,
iface
,
id
,
type
,
flags
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, type %p, flags %#lx.
\n
"
,
iface
,
id
,
type
,
flags
);
if
(
FAILED
(
hr
=
check_media_type
(
type
)))
return
hr
;
if
(
!
impl
->
input_type
&&
FAILED
(
hr
=
MFCreateMediaType
(
&
impl
->
input_type
)))
return
hr
;
if
(
impl
->
output_type
)
{
IMFMediaType_Release
(
impl
->
output_type
);
impl
->
output_type
=
NULL
;
}
if
(
FAILED
(
hr
=
IMFMediaType_CopyAllItems
(
type
,
(
IMFAttributes
*
)
impl
->
input_type
)))
{
IMFMediaType_Release
(
impl
->
input_type
);
impl
->
input_type
=
NULL
;
}
return
hr
;
}
static
HRESULT
WINAPI
transform_SetOutputType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
*
type
,
DWORD
flags
)
{
FIXME
(
"iface %p, id %#lx, type %p, flags %#lx stub!
\n
"
,
iface
,
id
,
type
,
flags
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, type %p, flags %#lx.
\n
"
,
iface
,
id
,
type
,
flags
);
if
(
!
impl
->
input_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
check_media_type
(
type
)))
return
hr
;
if
(
!
impl
->
output_type
&&
FAILED
(
hr
=
MFCreateMediaType
(
&
impl
->
output_type
)))
return
hr
;
if
(
FAILED
(
hr
=
IMFMediaType_CopyAllItems
(
type
,
(
IMFAttributes
*
)
impl
->
output_type
)))
goto
failed
;
if
(
FAILED
(
hr
=
try_create_wg_transform
(
impl
)))
goto
failed
;
return
hr
;
failed:
IMFMediaType_Release
(
impl
->
output_type
);
impl
->
output_type
=
NULL
;
return
hr
;
}
static
HRESULT
WINAPI
transform_GetInputCurrentType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
**
type
)
{
FIXME
(
"iface %p, id %#lx, type %p stub!
\n
"
,
iface
,
id
,
type
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
IMFMediaType
*
ret
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, type %p.
\n
"
,
iface
,
id
,
type
);
if
(
id
!=
0
)
return
MF_E_INVALIDSTREAMNUMBER
;
if
(
!
impl
->
input_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
MFCreateMediaType
(
&
ret
)))
return
hr
;
return
IMFMediaType_CopyAllItems
(
impl
->
input_type
,
(
IMFAttributes
*
)
ret
);
}
static
HRESULT
WINAPI
transform_GetOutputCurrentType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
**
type
)
{
FIXME
(
"iface %p, id %#lx, type %p stub!
\n
"
,
iface
,
id
,
type
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
IMFMediaType
*
ret
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, type %p.
\n
"
,
iface
,
id
,
type
);
if
(
id
!=
0
)
return
MF_E_INVALIDSTREAMNUMBER
;
if
(
!
impl
->
output_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
MFCreateMediaType
(
&
ret
)))
return
hr
;
return
IMFMediaType_CopyAllItems
(
impl
->
output_type
,
(
IMFAttributes
*
)
ret
);
}
static
HRESULT
WINAPI
transform_GetInputStatus
(
IMFTransform
*
iface
,
DWORD
id
,
DWORD
*
flags
)
...
...
@@ -250,20 +499,81 @@ static HRESULT WINAPI transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFM
static
HRESULT
WINAPI
transform_ProcessMessage
(
IMFTransform
*
iface
,
MFT_MESSAGE_TYPE
message
,
ULONG_PTR
param
)
{
FIXME
(
"iface %p, message %#x, param %p stub!
\n
"
,
iface
,
message
,
(
void
*
)
param
);
return
E_NOTIMPL
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_ProcessInput
(
IMFTransform
*
iface
,
DWORD
id
,
IMFSample
*
sample
,
DWORD
flags
)
{
FIXME
(
"iface %p, id %#lx, sample %p, flags %#lx stub!
\n
"
,
iface
,
id
,
sample
,
flags
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
struct
wg_sample
*
wg_sample
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, sample %p, flags %#lx.
\n
"
,
iface
,
id
,
sample
,
flags
);
if
(
!
impl
->
wg_transform
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
wg_sample_create_mf
(
sample
,
&
wg_sample
)))
return
hr
;
return
wg_transform_push_mf
(
impl
->
wg_transform
,
wg_sample
,
impl
->
wg_sample_queue
);
}
static
HRESULT
WINAPI
transform_ProcessOutput
(
IMFTransform
*
iface
,
DWORD
flags
,
DWORD
count
,
MFT_OUTPUT_DATA_BUFFER
*
samples
,
DWORD
*
status
)
{
FIXME
(
"iface %p, flags %#lx, count %lu, samples %p, status %p stub!
\n
"
,
iface
,
flags
,
count
,
samples
,
status
);
return
E_NOTIMPL
;
struct
resampler
*
impl
=
impl_from_IMFTransform
(
iface
);
MFT_OUTPUT_STREAM_INFO
info
;
struct
wg_sample
*
wg_sample
;
HRESULT
hr
;
TRACE
(
"iface %p, flags %#lx, count %lu, samples %p, status %p.
\n
"
,
iface
,
flags
,
count
,
samples
,
status
);
if
(
count
>
1
)
return
E_INVALIDARG
;
if
(
!
impl
->
wg_transform
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
IMFTransform_GetOutputStreamInfo
(
iface
,
0
,
&
info
)))
return
hr
;
*
status
=
0
;
samples
[
0
].
dwStatus
=
0
;
if
(
!
samples
[
0
].
pSample
)
{
samples
[
0
].
dwStatus
=
MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
;
return
MF_E_TRANSFORM_NEED_MORE_INPUT
;
}
if
(
FAILED
(
hr
=
wg_sample_create_mf
(
samples
[
0
].
pSample
,
&
wg_sample
)))
return
hr
;
wg_sample
->
size
=
0
;
if
(
wg_sample
->
max_size
<
info
.
cbSize
)
{
wg_sample_release
(
wg_sample
);
return
MF_E_BUFFERTOOSMALL
;
}
if
(
SUCCEEDED
(
hr
=
wg_transform_read_mf
(
impl
->
wg_transform
,
wg_sample
,
NULL
)))
{
if
(
wg_sample
->
flags
&
WG_SAMPLE_FLAG_INCOMPLETE
)
samples
[
0
].
dwStatus
|=
MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
;
wg_sample_queue_flush
(
impl
->
wg_sample_queue
,
false
);
}
wg_sample_release
(
wg_sample
);
if
(
hr
==
MF_E_TRANSFORM_STREAM_CHANGE
)
{
FIXME
(
"Unexpected stream format change!
\n
"
);
samples
[
0
].
dwStatus
|=
MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
;
*
status
|=
MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
;
}
return
hr
;
}
static
const
IMFTransformVtbl
transform_vtbl
=
...
...
@@ -318,8 +628,9 @@ static ULONG WINAPI media_object_Release(IMediaObject *iface)
static
HRESULT
WINAPI
media_object_GetStreamCount
(
IMediaObject
*
iface
,
DWORD
*
input
,
DWORD
*
output
)
{
FIXME
(
"iface %p, input %p, output %p stub!
\n
"
,
iface
,
input
,
output
);
return
E_NOTIMPL
;
FIXME
(
"iface %p, input %p, output %p semi-stub!
\n
"
,
iface
,
input
,
output
);
*
input
=
*
output
=
1
;
return
S_OK
;
}
static
HRESULT
WINAPI
media_object_GetInputStreamInfo
(
IMediaObject
*
iface
,
DWORD
index
,
DWORD
*
flags
)
...
...
@@ -585,13 +896,50 @@ static const IPropertyStoreVtbl property_store_vtbl =
HRESULT
resampler_create
(
IUnknown
*
outer
,
IUnknown
**
out
)
{
static
const
struct
wg_format
input_format
=
{
.
major_type
=
WG_MAJOR_TYPE_AUDIO
,
.
u
.
audio
=
{
.
format
=
WG_AUDIO_FORMAT_S16LE
,
.
channel_mask
=
1
,
.
channels
=
1
,
.
rate
=
44100
,
},
};
static
const
struct
wg_format
output_format
=
{
.
major_type
=
WG_MAJOR_TYPE_AUDIO
,
.
u
.
audio
=
{
.
format
=
WG_AUDIO_FORMAT_F32LE
,
.
channel_mask
=
1
,
.
channels
=
1
,
.
rate
=
44100
,
},
};
struct
wg_transform
*
transform
;
struct
resampler
*
impl
;
HRESULT
hr
;
TRACE
(
"outer %p, out %p.
\n
"
,
outer
,
out
);
if
(
!
(
transform
=
wg_transform_create
(
&
input_format
,
&
output_format
)))
{
ERR_
(
winediag
)(
"GStreamer doesn't support audio resampling, please install appropriate plugins.
\n
"
);
return
E_FAIL
;
}
wg_transform_destroy
(
transform
);
if
(
!
(
impl
=
calloc
(
1
,
sizeof
(
*
impl
))))
return
E_OUTOFMEMORY
;
if
(
FAILED
(
hr
=
wg_sample_queue_create
(
&
impl
->
wg_sample_queue
)))
{
free
(
impl
);
return
hr
;
}
impl
->
IUnknown_inner
.
lpVtbl
=
&
unknown_vtbl
;
impl
->
IMFTransform_iface
.
lpVtbl
=
&
transform_vtbl
;
impl
->
IMediaObject_iface
.
lpVtbl
=
&
media_object_vtbl
;
...
...
dlls/winegstreamer/wg_transform.c
View file @
d33cb57e
...
...
@@ -406,6 +406,7 @@ NTSTATUS wg_transform_create(void *args)
break
;
case
WG_MAJOR_TYPE_AUDIO
:
break
;
case
WG_MAJOR_TYPE_VIDEO
:
case
WG_MAJOR_TYPE_UNKNOWN
:
GST_FIXME
(
"Format %u not implemented!"
,
input_format
.
major_type
);
...
...
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