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
a21e7c46
Commit
a21e7c46
authored
Aug 12, 2022
by
Rémi Bernon
Committed by
Alexandre Julliard
Oct 14, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Implement AAC decoder MFT.
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=47084
parent
4199bb7f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
395 additions
and
32 deletions
+395
-32
transform.c
dlls/mf/tests/transform.c
+1
-8
aac_decoder.c
dlls/winegstreamer/aac_decoder.c
+394
-24
No files found.
dlls/mf/tests/transform.c
View file @
a21e7c46
...
...
@@ -1918,13 +1918,10 @@ static void test_aac_decoder(void)
check_mft_optional_methods
(
transform
,
1
);
check_mft_get_attributes
(
transform
,
expect_transform_attributes
,
FALSE
);
todo_wine
check_mft_get_input_stream_info
(
transform
,
S_OK
,
&
input_info
);
todo_wine
check_mft_get_output_stream_info
(
transform
,
S_OK
,
&
output_info
);
hr
=
IMFTransform_GetOutputAvailableType
(
transform
,
0
,
0
,
&
media_type
);
todo_wine
ok
(
hr
==
MF_E_TRANSFORM_TYPE_NOT_SET
,
"GetOutputAvailableType returned %#lx
\n
"
,
hr
);
i
=
-
1
;
...
...
@@ -1938,14 +1935,10 @@ static void test_aac_decoder(void)
ok
(
ret
<=
1
,
"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
==
ARRAY_SIZE
(
expect_available_inputs
)
||
broken
(
i
==
2
)
/* w7 */
||
broken
(
i
==
4
)
/* w8 */
,
"%lu input media types
\n
"
,
i
);
if
(
hr
==
E_NOTIMPL
)
goto
skip_tests
;
/* setting output media type first doesn't work */
check_mft_set_output_type
(
transform
,
output_type_desc
,
MF_E_TRANSFORM_TYPE_NOT_SET
);
...
...
@@ -2023,6 +2016,7 @@ static void test_aac_decoder(void)
ok
(
i
==
1
,
"got %lu output samples
\n
"
,
i
);
ret
=
check_mf_sample_collection
(
output_samples
,
output_sample_desc
,
L"aacdecdata.bin"
);
todo_wine_if
(
ret
<=
5
)
ok
(
ret
==
0
,
"got %lu%% diff
\n
"
,
ret
);
IMFCollection_Release
(
output_samples
);
...
...
@@ -2038,7 +2032,6 @@ static void test_aac_decoder(void)
ret
=
IMFSample_Release
(
input_sample
);
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
skip_tests:
ret
=
IMFTransform_Release
(
transform
);
ok
(
ret
==
0
,
"Release returned %lu
\n
"
,
ret
);
...
...
dlls/winegstreamer/aac_decoder.c
View file @
a21e7c46
...
...
@@ -28,11 +28,37 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
mfplat
);
WINE_DECLARE_DEBUG_CHANNEL
(
winediag
);
extern
const
GUID
MFAudioFormat_RAW_AAC
;
static
struct
{
const
GUID
*
const
guid
;
UINT32
payload_type
;
}
aac_decoder_input_types
[]
=
{
{
&
MFAudioFormat_AAC
,
0
},
{
&
MFAudioFormat_RAW_AAC
,
-
1
},
{
&
MFAudioFormat_AAC
,
1
},
{
&
MFAudioFormat_AAC
,
3
},
{
&
MFAudioFormat_ADTS
,
-
1
},
};
static
const
GUID
*
const
aac_decoder_output_types
[]
=
{
&
MFAudioFormat_PCM
,
&
MFAudioFormat_Float
,
};
struct
aac_decoder
{
IMFTransform
IMFTransform_iface
;
LONG
refcount
;
IMFMediaType
*
input_type
;
IMFMediaType
*
output_type
;
struct
wg_transform
*
wg_transform
;
struct
wg_sample_queue
*
wg_sample_queue
;
};
static
struct
aac_decoder
*
impl_from_IMFTransform
(
IMFTransform
*
iface
)
...
...
@@ -40,14 +66,35 @@ static struct aac_decoder *impl_from_IMFTransform(IMFTransform *iface)
return
CONTAINING_RECORD
(
iface
,
struct
aac_decoder
,
IMFTransform_iface
);
}
static
HRESULT
try_create_wg_transform
(
struct
aac_decoder
*
decoder
)
{
struct
wg_format
input_format
,
output_format
;
if
(
decoder
->
wg_transform
)
wg_transform_destroy
(
decoder
->
wg_transform
);
decoder
->
wg_transform
=
NULL
;
mf_media_type_to_wg_format
(
decoder
->
input_type
,
&
input_format
);
if
(
input_format
.
major_type
==
WG_MAJOR_TYPE_UNKNOWN
)
return
MF_E_INVALIDMEDIATYPE
;
mf_media_type_to_wg_format
(
decoder
->
output_type
,
&
output_format
);
if
(
output_format
.
major_type
==
WG_MAJOR_TYPE_UNKNOWN
)
return
MF_E_INVALIDMEDIATYPE
;
if
(
!
(
decoder
->
wg_transform
=
wg_transform_create
(
&
input_format
,
&
output_format
)))
return
E_FAIL
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_QueryInterface
(
IMFTransform
*
iface
,
REFIID
iid
,
void
**
out
)
{
struct
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
TRACE
(
"iface %p, iid %s, out %p.
\n
"
,
iface
,
debugstr_guid
(
iid
),
out
);
if
(
IsEqualGUID
(
iid
,
&
IID_IUnknown
)
||
IsEqualGUID
(
iid
,
&
IID_IMFTransform
))
if
(
IsEqualGUID
(
iid
,
&
IID_IUnknown
)
||
IsEqualGUID
(
iid
,
&
IID_IMFTransform
))
*
out
=
&
decoder
->
IMFTransform_iface
;
else
{
...
...
@@ -76,7 +123,16 @@ static ULONG WINAPI transform_Release(IMFTransform *iface)
TRACE
(
"iface %p decreasing refcount to %lu.
\n
"
,
decoder
,
refcount
);
if
(
!
refcount
)
{
if
(
decoder
->
wg_transform
)
wg_transform_destroy
(
decoder
->
wg_transform
);
if
(
decoder
->
input_type
)
IMFMediaType_Release
(
decoder
->
input_type
);
if
(
decoder
->
output_type
)
IMFMediaType_Release
(
decoder
->
output_type
);
wg_sample_queue_destroy
(
decoder
->
wg_sample_queue
);
free
(
decoder
);
}
return
refcount
;
}
...
...
@@ -107,14 +163,30 @@ 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
;
TRACE
(
"iface %p, id %#lx, info %p.
\n
"
,
iface
,
id
,
info
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
memset
(
info
,
0
,
sizeof
(
*
info
));
info
->
dwFlags
=
MFT_INPUT_STREAM_WHOLE_SAMPLES
|
MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
|
MFT_INPUT_STREAM_HOLDS_BUFFERS
;
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
;
TRACE
(
"iface %p, id %#lx, info %p.
\n
"
,
iface
,
id
,
info
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
memset
(
info
,
0
,
sizeof
(
*
info
));
info
->
dwFlags
=
MFT_INPUT_STREAM_WHOLE_SAMPLES
;
info
->
cbSize
=
0xc000
;
return
S_OK
;
}
static
HRESULT
WINAPI
transform_GetAttributes
(
IMFTransform
*
iface
,
IMFAttributes
**
attributes
)
...
...
@@ -150,39 +222,280 @@ static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD strea
static
HRESULT
WINAPI
transform_GetInputAvailableType
(
IMFTransform
*
iface
,
DWORD
id
,
DWORD
index
,
IMFMediaType
**
type
)
{
FIXME
(
"iface %p, id %#lx, index %#lx, type %p stub!
\n
"
,
iface
,
id
,
index
,
type
);
return
E_NOTIMPL
;
IMFMediaType
*
media_type
;
const
GUID
*
subtype
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, index %#lx, type %p.
\n
"
,
iface
,
id
,
index
,
type
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
*
type
=
NULL
;
if
(
index
>=
ARRAY_SIZE
(
aac_decoder_input_types
))
return
MF_E_NO_MORE_TYPES
;
subtype
=
aac_decoder_input_types
[
index
].
guid
;
if
(
FAILED
(
hr
=
MFCreateMediaType
(
&
media_type
)))
return
hr
;
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_AUDIO_BITS_PER_SAMPLE
,
32
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_NUM_CHANNELS
,
6
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_BLOCK_ALIGNMENT
,
24
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_SAMPLES_PER_SECOND
,
48000
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_AVG_BYTES_PER_SECOND
,
1152000
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_PREFER_WAVEFORMATEX
,
1
)))
goto
done
;
if
(
IsEqualGUID
(
subtype
,
&
MFAudioFormat_AAC
))
{
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
,
0
)))
goto
done
;
if
(
aac_decoder_input_types
[
index
].
payload_type
!=
-
1
&&
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AAC_PAYLOAD_TYPE
,
aac_decoder_input_types
[
index
].
payload_type
)))
goto
done
;
}
done:
if
(
SUCCEEDED
(
hr
))
IMFMediaType_AddRef
((
*
type
=
media_type
));
IMFMediaType_Release
(
media_type
);
return
hr
;
}
static
HRESULT
WINAPI
transform_GetOutputAvailableType
(
IMFTransform
*
iface
,
DWORD
id
,
DWORD
index
,
IMFMediaType
**
type
)
{
FIXME
(
"iface %p, id %#lx, index %#lx, type %p stub!
\n
"
,
iface
,
id
,
index
,
type
);
return
E_NOTIMPL
;
UINT32
channel_count
,
sample_size
,
sample_rate
,
block_alignment
;
struct
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
IMFMediaType
*
media_type
;
const
GUID
*
output_type
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, index %#lx, type %p.
\n
"
,
iface
,
id
,
index
,
type
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
if
(
!
decoder
->
input_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
*
type
=
NULL
;
if
(
index
>=
ARRAY_SIZE
(
aac_decoder_output_types
))
return
MF_E_NO_MORE_TYPES
;
index
=
ARRAY_SIZE
(
aac_decoder_output_types
)
-
index
-
1
;
output_type
=
aac_decoder_output_types
[
index
];
if
(
FAILED
(
hr
=
MFCreateMediaType
(
&
media_type
)))
return
hr
;
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
,
output_type
)))
goto
done
;
if
(
IsEqualGUID
(
output_type
,
&
MFAudioFormat_Float
))
sample_size
=
32
;
else
if
(
IsEqualGUID
(
output_type
,
&
MFAudioFormat_PCM
))
sample_size
=
16
;
else
{
FIXME
(
"Subtype %s not implemented!
\n
"
,
debugstr_guid
(
output_type
));
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_GetUINT32
(
decoder
->
input_type
,
&
MF_MT_AUDIO_NUM_CHANNELS
,
&
channel_count
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_AUDIO_NUM_CHANNELS
,
channel_count
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_GetUINT32
(
decoder
->
input_type
,
&
MF_MT_AUDIO_SAMPLES_PER_SECOND
,
&
sample_rate
)))
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_ALL_SAMPLES_INDEPENDENT
,
1
)))
goto
done
;
if
(
FAILED
(
hr
=
IMFMediaType_SetUINT32
(
media_type
,
&
MF_MT_FIXED_SIZE_SAMPLES
,
1
)))
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_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
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
MF_ATTRIBUTE_TYPE
item_type
;
GUID
major
,
subtype
;
HRESULT
hr
;
ULONG
i
;
TRACE
(
"iface %p, id %#lx, type %p, flags %#lx.
\n
"
,
iface
,
id
,
type
,
flags
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
if
(
FAILED
(
hr
=
IMFMediaType_GetGUID
(
type
,
&
MF_MT_MAJOR_TYPE
,
&
major
)))
return
E_INVALIDARG
;
if
(
!
IsEqualGUID
(
&
major
,
&
MFMediaType_Audio
)
||
FAILED
(
hr
=
IMFMediaType_GetGUID
(
type
,
&
MF_MT_SUBTYPE
,
&
subtype
)))
return
MF_E_INVALIDMEDIATYPE
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
aac_decoder_input_types
);
++
i
)
if
(
IsEqualGUID
(
&
subtype
,
aac_decoder_input_types
[
i
].
guid
))
break
;
if
(
i
==
ARRAY_SIZE
(
aac_decoder_input_types
))
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_USER_DATA
,
&
item_type
))
||
item_type
!=
MF_ATTRIBUTE_BLOB
)
return
MF_E_INVALIDMEDIATYPE
;
if
(
flags
&
MFT_SET_TYPE_TEST_ONLY
)
return
S_OK
;
if
(
!
decoder
->
input_type
&&
FAILED
(
hr
=
MFCreateMediaType
(
&
decoder
->
input_type
)))
return
hr
;
if
(
decoder
->
output_type
)
{
IMFMediaType_Release
(
decoder
->
output_type
);
decoder
->
output_type
=
NULL
;
}
return
IMFMediaType_CopyAllItems
(
type
,
(
IMFAttributes
*
)
decoder
->
input_type
);
}
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
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
MF_ATTRIBUTE_TYPE
item_type
;
GUID
major
,
subtype
;
HRESULT
hr
;
ULONG
i
;
TRACE
(
"iface %p, id %#lx, type %p, flags %#lx.
\n
"
,
iface
,
id
,
type
,
flags
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
if
(
!
decoder
->
input_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
IMFMediaType_GetGUID
(
type
,
&
MF_MT_MAJOR_TYPE
,
&
major
))
||
FAILED
(
hr
=
IMFMediaType_GetGUID
(
type
,
&
MF_MT_SUBTYPE
,
&
subtype
)))
return
hr
;
if
(
!
IsEqualGUID
(
&
major
,
&
MFMediaType_Audio
))
return
MF_E_INVALIDMEDIATYPE
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
aac_decoder_output_types
);
++
i
)
if
(
IsEqualGUID
(
&
subtype
,
aac_decoder_output_types
[
i
]))
break
;
if
(
i
==
ARRAY_SIZE
(
aac_decoder_output_types
))
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_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
(
flags
&
MFT_SET_TYPE_TEST_ONLY
)
return
S_OK
;
if
(
!
decoder
->
output_type
&&
FAILED
(
hr
=
MFCreateMediaType
(
&
decoder
->
output_type
)))
return
hr
;
if
(
FAILED
(
hr
=
IMFMediaType_CopyAllItems
(
type
,
(
IMFAttributes
*
)
decoder
->
output_type
)))
return
hr
;
if
(
FAILED
(
hr
=
try_create_wg_transform
(
decoder
)))
goto
failed
;
return
S_OK
;
failed:
IMFMediaType_Release
(
decoder
->
output_type
);
decoder
->
output_type
=
NULL
;
return
hr
;
}
static
HRESULT
WINAPI
transform_GetInputCurrentType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
**
type
)
static
HRESULT
WINAPI
transform_GetInputCurrentType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
**
out
)
{
FIXME
(
"iface %p, id %#lx, type %p stub!
\n
"
,
iface
,
id
,
type
);
return
E_NOTIMPL
;
struct
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
IMFMediaType
*
type
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, out %p.
\n
"
,
iface
,
id
,
out
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
if
(
!
decoder
->
input_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
MFCreateMediaType
(
&
type
)))
return
hr
;
if
(
SUCCEEDED
(
hr
=
IMFMediaType_CopyAllItems
(
decoder
->
input_type
,
(
IMFAttributes
*
)
type
)))
IMFMediaType_AddRef
(
*
out
=
type
);
IMFMediaType_Release
(
type
);
return
hr
;
}
static
HRESULT
WINAPI
transform_GetOutputCurrentType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
**
type
)
static
HRESULT
WINAPI
transform_GetOutputCurrentType
(
IMFTransform
*
iface
,
DWORD
id
,
IMFMediaType
**
out
)
{
FIXME
(
"iface %p, id %#lx, type %p stub!
\n
"
,
iface
,
id
,
type
);
return
E_NOTIMPL
;
struct
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
IMFMediaType
*
type
;
HRESULT
hr
;
TRACE
(
"iface %p, id %#lx, out %p.
\n
"
,
iface
,
id
,
out
);
if
(
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
if
(
!
decoder
->
output_type
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
if
(
FAILED
(
hr
=
MFCreateMediaType
(
&
type
)))
return
hr
;
if
(
SUCCEEDED
(
hr
=
IMFMediaType_CopyAllItems
(
decoder
->
output_type
,
(
IMFAttributes
*
)
type
)))
IMFMediaType_AddRef
(
*
out
=
type
);
IMFMediaType_Release
(
type
);
return
hr
;
}
static
HRESULT
WINAPI
transform_GetInputStatus
(
IMFTransform
*
iface
,
DWORD
id
,
DWORD
*
flags
)
...
...
@@ -217,15 +530,45 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_
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
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
TRACE
(
"iface %p, id %#lx, sample %p, flags %#lx.
\n
"
,
iface
,
id
,
sample
,
flags
);
if
(
!
decoder
->
wg_transform
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
return
wg_transform_push_mf
(
decoder
->
wg_transform
,
sample
,
decoder
->
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
aac_decoder
*
decoder
=
impl_from_IMFTransform
(
iface
);
MFT_OUTPUT_STREAM_INFO
info
;
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
(
!
decoder
->
wg_transform
)
return
MF_E_TRANSFORM_TYPE_NOT_SET
;
*
status
=
samples
->
dwStatus
=
0
;
if
(
!
samples
->
pSample
)
return
E_INVALIDARG
;
if
(
FAILED
(
hr
=
IMFTransform_GetOutputStreamInfo
(
iface
,
0
,
&
info
)))
return
hr
;
if
(
SUCCEEDED
(
hr
=
wg_transform_read_mf
(
decoder
->
wg_transform
,
samples
->
pSample
,
info
.
cbSize
,
NULL
,
&
samples
->
dwStatus
)))
wg_sample_queue_flush
(
decoder
->
wg_sample_queue
,
false
);
else
samples
->
dwStatus
=
MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
;
return
hr
;
}
static
const
IMFTransformVtbl
transform_vtbl
=
...
...
@@ -260,13 +603,40 @@ static const IMFTransformVtbl transform_vtbl =
HRESULT
aac_decoder_create
(
REFIID
riid
,
void
**
ret
)
{
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
,
},
};
static
const
struct
wg_format
input_format
=
{.
major_type
=
WG_MAJOR_TYPE_AUDIO_MPEG4
};
struct
wg_transform
*
transform
;
struct
aac_decoder
*
decoder
;
HRESULT
hr
;
TRACE
(
"riid %s, ret %p.
\n
"
,
debugstr_guid
(
riid
),
ret
);
if
(
!
(
transform
=
wg_transform_create
(
&
input_format
,
&
output_format
)))
{
ERR_
(
winediag
)(
"GStreamer doesn't support WMA decoding, please install appropriate plugins
\n
"
);
return
E_FAIL
;
}
wg_transform_destroy
(
transform
);
if
(
!
(
decoder
=
calloc
(
1
,
sizeof
(
*
decoder
))))
return
E_OUTOFMEMORY
;
if
(
FAILED
(
hr
=
wg_sample_queue_create
(
&
decoder
->
wg_sample_queue
)))
{
free
(
decoder
);
return
hr
;
}
decoder
->
IMFTransform_iface
.
lpVtbl
=
&
transform_vtbl
;
decoder
->
refcount
=
1
;
...
...
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