1 /* WMA Decoder DMO / MF Transform
3 * Copyright 2022 RĂ©mi Bernon for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "gst_private.h"
24 #include "mfobjects.h"
25 #include "mftransform.h"
26 #include "wmcodecdsp.h"
28 #include "wine/debug.h"
29 #include "wine/heap.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wmadec
);
33 static const GUID
*const wma_decoder_input_types
[] =
35 &MEDIASUBTYPE_MSAUDIO1
,
36 &MFAudioFormat_WMAudioV8
,
37 &MFAudioFormat_WMAudioV9
,
38 &MFAudioFormat_WMAudio_Lossless
,
40 static const GUID
*const wma_decoder_output_types
[] =
48 IUnknown IUnknown_inner
;
49 IMFTransform IMFTransform_iface
;
50 IMediaObject IMediaObject_iface
;
51 IPropertyBag IPropertyBag_iface
;
54 IMFMediaType
*input_type
;
55 IMFMediaType
*output_type
;
57 struct wg_transform
*wg_transform
;
60 static inline struct wma_decoder
*impl_from_IUnknown(IUnknown
*iface
)
62 return CONTAINING_RECORD(iface
, struct wma_decoder
, IUnknown_inner
);
65 static HRESULT
try_create_wg_transform(struct wma_decoder
*decoder
)
67 struct wg_format input_format
, output_format
;
69 if (decoder
->wg_transform
)
70 wg_transform_destroy(decoder
->wg_transform
);
71 decoder
->wg_transform
= NULL
;
73 mf_media_type_to_wg_format(decoder
->input_type
, &input_format
);
74 if (input_format
.major_type
== WG_MAJOR_TYPE_UNKNOWN
)
75 return MF_E_INVALIDMEDIATYPE
;
77 mf_media_type_to_wg_format(decoder
->output_type
, &output_format
);
78 if (output_format
.major_type
== WG_MAJOR_TYPE_UNKNOWN
)
79 return MF_E_INVALIDMEDIATYPE
;
81 if (!(decoder
->wg_transform
= wg_transform_create(&input_format
, &output_format
)))
87 static HRESULT WINAPI
unknown_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
89 struct wma_decoder
*decoder
= impl_from_IUnknown(iface
);
91 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
93 if (IsEqualGUID(iid
, &IID_IUnknown
))
94 *out
= &decoder
->IUnknown_inner
;
95 else if (IsEqualGUID(iid
, &IID_IMFTransform
))
96 *out
= &decoder
->IMFTransform_iface
;
97 else if (IsEqualGUID(iid
, &IID_IMediaObject
))
98 *out
= &decoder
->IMediaObject_iface
;
99 else if (IsEqualIID(iid
, &IID_IPropertyBag
))
100 *out
= &decoder
->IPropertyBag_iface
;
104 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
105 return E_NOINTERFACE
;
108 IUnknown_AddRef((IUnknown
*)*out
);
112 static ULONG WINAPI
unknown_AddRef(IUnknown
*iface
)
114 struct wma_decoder
*decoder
= impl_from_IUnknown(iface
);
115 ULONG refcount
= InterlockedIncrement(&decoder
->refcount
);
117 TRACE("iface %p increasing refcount to %lu.\n", decoder
, refcount
);
122 static ULONG WINAPI
unknown_Release(IUnknown
*iface
)
124 struct wma_decoder
*decoder
= impl_from_IUnknown(iface
);
125 ULONG refcount
= InterlockedDecrement(&decoder
->refcount
);
127 TRACE("iface %p decreasing refcount to %lu.\n", decoder
, refcount
);
131 if (decoder
->wg_transform
)
132 wg_transform_destroy(decoder
->wg_transform
);
133 if (decoder
->input_type
)
134 IMFMediaType_Release(decoder
->input_type
);
135 if (decoder
->output_type
)
136 IMFMediaType_Release(decoder
->output_type
);
143 static const IUnknownVtbl unknown_vtbl
=
145 unknown_QueryInterface
,
150 static struct wma_decoder
*impl_from_IMFTransform(IMFTransform
*iface
)
152 return CONTAINING_RECORD(iface
, struct wma_decoder
, IMFTransform_iface
);
155 static HRESULT WINAPI
transform_QueryInterface(IMFTransform
*iface
, REFIID iid
, void **out
)
157 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
158 return IUnknown_QueryInterface(decoder
->outer
, iid
, out
);
161 static ULONG WINAPI
transform_AddRef(IMFTransform
*iface
)
163 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
164 return IUnknown_AddRef(decoder
->outer
);
167 static ULONG WINAPI
transform_Release(IMFTransform
*iface
)
169 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
170 return IUnknown_Release(decoder
->outer
);
173 static HRESULT WINAPI
transform_GetStreamLimits(IMFTransform
*iface
, DWORD
*input_minimum
,
174 DWORD
*input_maximum
, DWORD
*output_minimum
, DWORD
*output_maximum
)
176 FIXME("iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p stub!\n",
177 iface
, input_minimum
, input_maximum
, output_minimum
, output_maximum
);
181 static HRESULT WINAPI
transform_GetStreamCount(IMFTransform
*iface
, DWORD
*inputs
, DWORD
*outputs
)
183 FIXME("iface %p, inputs %p, outputs %p stub!\n", iface
, inputs
, outputs
);
187 static HRESULT WINAPI
transform_GetStreamIDs(IMFTransform
*iface
, DWORD input_size
, DWORD
*inputs
,
188 DWORD output_size
, DWORD
*outputs
)
190 FIXME("iface %p, input_size %lu, inputs %p, output_size %lu, outputs %p stub!\n", iface
,
191 input_size
, inputs
, output_size
, outputs
);
195 static HRESULT WINAPI
transform_GetInputStreamInfo(IMFTransform
*iface
, DWORD id
, MFT_INPUT_STREAM_INFO
*info
)
197 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
198 UINT32 block_alignment
;
201 TRACE("iface %p, id %lu, info %p.\n", iface
, id
, info
);
203 if (!decoder
->input_type
|| !decoder
->output_type
)
204 return MF_E_TRANSFORM_TYPE_NOT_SET
;
206 if (FAILED(hr
= IMFMediaType_GetUINT32(decoder
->input_type
, &MF_MT_AUDIO_BLOCK_ALIGNMENT
, &block_alignment
)))
209 info
->hnsMaxLatency
= 0;
211 info
->cbSize
= block_alignment
;
212 info
->cbMaxLookahead
= 0;
213 info
->cbAlignment
= 1;
218 static HRESULT WINAPI
transform_GetOutputStreamInfo(IMFTransform
*iface
, DWORD id
, MFT_OUTPUT_STREAM_INFO
*info
)
220 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
221 UINT32 channel_count
, block_alignment
;
224 TRACE("iface %p, id %lu, info %p.\n", iface
, id
, info
);
226 if (!decoder
->input_type
|| !decoder
->output_type
)
227 return MF_E_TRANSFORM_TYPE_NOT_SET
;
229 if (FAILED(hr
= IMFMediaType_GetUINT32(decoder
->output_type
, &MF_MT_AUDIO_NUM_CHANNELS
, &channel_count
)))
231 if (FAILED(hr
= IMFMediaType_GetUINT32(decoder
->output_type
, &MF_MT_AUDIO_BLOCK_ALIGNMENT
, &block_alignment
)))
235 info
->cbSize
= 1024 * block_alignment
* channel_count
;
236 info
->cbAlignment
= 1;
241 static HRESULT WINAPI
transform_GetAttributes(IMFTransform
*iface
, IMFAttributes
**attributes
)
243 FIXME("iface %p, attributes %p stub!\n", iface
, attributes
);
247 static HRESULT WINAPI
transform_GetInputStreamAttributes(IMFTransform
*iface
, DWORD id
, IMFAttributes
**attributes
)
249 FIXME("iface %p, id %lu, attributes %p stub!\n", iface
, id
, attributes
);
253 static HRESULT WINAPI
transform_GetOutputStreamAttributes(IMFTransform
*iface
, DWORD id
, IMFAttributes
**attributes
)
255 FIXME("iface %p, id %lu, attributes %p stub!\n", iface
, id
, attributes
);
259 static HRESULT WINAPI
transform_DeleteInputStream(IMFTransform
*iface
, DWORD id
)
261 FIXME("iface %p, id %lu stub!\n", iface
, id
);
265 static HRESULT WINAPI
transform_AddInputStreams(IMFTransform
*iface
, DWORD streams
, DWORD
*ids
)
267 FIXME("iface %p, streams %lu, ids %p stub!\n", iface
, streams
, ids
);
271 static HRESULT WINAPI
transform_GetInputAvailableType(IMFTransform
*iface
, DWORD id
, DWORD index
,
274 FIXME("iface %p, id %lu, index %lu, type %p stub!\n", iface
, id
, index
, type
);
278 static HRESULT WINAPI
transform_GetOutputAvailableType(IMFTransform
*iface
, DWORD id
, DWORD index
,
281 UINT32 channel_count
, sample_size
, sample_rate
, block_alignment
;
282 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
283 IMFMediaType
*media_type
;
284 const GUID
*output_type
;
287 TRACE("iface %p, id %lu, index %lu, type %p.\n", iface
, id
, index
, type
);
289 if (!decoder
->input_type
)
290 return MF_E_TRANSFORM_TYPE_NOT_SET
;
294 if (index
>= ARRAY_SIZE(wma_decoder_output_types
))
295 return MF_E_NO_MORE_TYPES
;
296 output_type
= wma_decoder_output_types
[index
];
298 if (FAILED(hr
= MFCreateMediaType(&media_type
)))
301 if (FAILED(hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
)))
303 if (FAILED(hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, output_type
)))
306 if (IsEqualGUID(output_type
, &MFAudioFormat_Float
))
308 else if (IsEqualGUID(output_type
, &MFAudioFormat_PCM
))
312 FIXME("Subtype %s not implemented!\n", debugstr_guid(output_type
));
317 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, sample_size
)))
320 if (FAILED(hr
= IMFMediaType_GetUINT32(decoder
->input_type
, &MF_MT_AUDIO_NUM_CHANNELS
, &channel_count
)))
322 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_NUM_CHANNELS
, channel_count
)))
325 if (FAILED(hr
= IMFMediaType_GetUINT32(decoder
->input_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, &sample_rate
)))
327 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, sample_rate
)))
330 block_alignment
= sample_size
* channel_count
/ 8;
331 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_BLOCK_ALIGNMENT
, block_alignment
)))
333 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, sample_rate
* block_alignment
)))
336 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, 1)))
338 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_FIXED_SIZE_SAMPLES
, 1)))
340 if (FAILED(hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1)))
345 IMFMediaType_AddRef((*type
= media_type
));
347 IMFMediaType_Release(media_type
);
351 static HRESULT WINAPI
transform_SetInputType(IMFTransform
*iface
, DWORD id
, IMFMediaType
*type
, DWORD flags
)
353 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
354 MF_ATTRIBUTE_TYPE item_type
;
359 TRACE("iface %p, id %lu, type %p, flags %#lx.\n", iface
, id
, type
, flags
);
361 if (FAILED(hr
= IMFMediaType_GetGUID(type
, &MF_MT_MAJOR_TYPE
, &major
)) ||
362 FAILED(hr
= IMFMediaType_GetGUID(type
, &MF_MT_SUBTYPE
, &subtype
)))
365 if (!IsEqualGUID(&major
, &MFMediaType_Audio
))
366 return MF_E_INVALIDMEDIATYPE
;
368 for (i
= 0; i
< ARRAY_SIZE(wma_decoder_input_types
); ++i
)
369 if (IsEqualGUID(&subtype
, wma_decoder_input_types
[i
]))
371 if (i
== ARRAY_SIZE(wma_decoder_input_types
))
372 return MF_E_INVALIDMEDIATYPE
;
374 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_USER_DATA
, &item_type
)) ||
375 item_type
!= MF_ATTRIBUTE_BLOB
)
376 return MF_E_INVALIDMEDIATYPE
;
377 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_BLOCK_ALIGNMENT
, &item_type
)) ||
378 item_type
!= MF_ATTRIBUTE_UINT32
)
379 return MF_E_INVALIDMEDIATYPE
;
380 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, &item_type
)) ||
381 item_type
!= MF_ATTRIBUTE_UINT32
)
382 return MF_E_INVALIDMEDIATYPE
;
383 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_NUM_CHANNELS
, &item_type
)) ||
384 item_type
!= MF_ATTRIBUTE_UINT32
)
385 return MF_E_INVALIDMEDIATYPE
;
387 if (!decoder
->input_type
&& FAILED(hr
= MFCreateMediaType(&decoder
->input_type
)))
390 if (decoder
->output_type
)
392 IMFMediaType_Release(decoder
->output_type
);
393 decoder
->output_type
= NULL
;
396 if (FAILED(hr
= IMFMediaType_CopyAllItems(type
, (IMFAttributes
*)decoder
->input_type
)))
398 IMFMediaType_Release(decoder
->input_type
);
399 decoder
->input_type
= NULL
;
405 static HRESULT WINAPI
transform_SetOutputType(IMFTransform
*iface
, DWORD id
, IMFMediaType
*type
, DWORD flags
)
407 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
408 MF_ATTRIBUTE_TYPE item_type
;
409 ULONG i
, sample_size
;
413 TRACE("iface %p, id %lu, type %p, flags %#lx.\n", iface
, id
, type
, flags
);
415 if (!decoder
->input_type
)
416 return MF_E_TRANSFORM_TYPE_NOT_SET
;
418 if (FAILED(hr
= IMFMediaType_GetGUID(type
, &MF_MT_MAJOR_TYPE
, &major
)) ||
419 FAILED(hr
= IMFMediaType_GetGUID(type
, &MF_MT_SUBTYPE
, &subtype
)))
422 if (!IsEqualGUID(&major
, &MFMediaType_Audio
))
423 return MF_E_INVALIDMEDIATYPE
;
425 for (i
= 0; i
< ARRAY_SIZE(wma_decoder_output_types
); ++i
)
426 if (IsEqualGUID(&subtype
, wma_decoder_output_types
[i
]))
428 if (i
== ARRAY_SIZE(wma_decoder_output_types
))
429 return MF_E_INVALIDMEDIATYPE
;
431 if (IsEqualGUID(&subtype
, &MFAudioFormat_Float
))
433 else if (IsEqualGUID(&subtype
, &MFAudioFormat_PCM
))
437 FIXME("Subtype %s not implemented!\n", debugstr_guid(&subtype
));
442 if (FAILED(IMFMediaType_SetUINT32(decoder
->input_type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, sample_size
)))
443 return MF_E_INVALIDMEDIATYPE
;
445 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, &item_type
)) ||
446 item_type
!= MF_ATTRIBUTE_UINT32
)
447 return MF_E_INVALIDMEDIATYPE
;
448 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_BITS_PER_SAMPLE
, &item_type
)) ||
449 item_type
!= MF_ATTRIBUTE_UINT32
)
450 return MF_E_INVALIDMEDIATYPE
;
451 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_NUM_CHANNELS
, &item_type
)) ||
452 item_type
!= MF_ATTRIBUTE_UINT32
)
453 return MF_E_INVALIDMEDIATYPE
;
454 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, &item_type
)) ||
455 item_type
!= MF_ATTRIBUTE_UINT32
)
456 return MF_E_INVALIDMEDIATYPE
;
457 if (FAILED(IMFMediaType_GetItemType(type
, &MF_MT_AUDIO_BLOCK_ALIGNMENT
, &item_type
)) ||
458 item_type
!= MF_ATTRIBUTE_UINT32
)
459 return MF_E_INVALIDMEDIATYPE
;
461 if (!decoder
->output_type
&& FAILED(hr
= MFCreateMediaType(&decoder
->output_type
)))
464 if (FAILED(hr
= IMFMediaType_CopyAllItems(type
, (IMFAttributes
*)decoder
->output_type
)))
467 if (FAILED(hr
= try_create_wg_transform(decoder
)))
473 IMFMediaType_Release(decoder
->output_type
);
474 decoder
->output_type
= NULL
;
478 static HRESULT WINAPI
transform_GetInputCurrentType(IMFTransform
*iface
, DWORD id
, IMFMediaType
**type
)
480 FIXME("iface %p, id %lu, type %p stub!\n", iface
, id
, type
);
484 static HRESULT WINAPI
transform_GetOutputCurrentType(IMFTransform
*iface
, DWORD id
, IMFMediaType
**type
)
486 FIXME("iface %p, id %lu, type %p stub!\n", iface
, id
, type
);
490 static HRESULT WINAPI
transform_GetInputStatus(IMFTransform
*iface
, DWORD id
, DWORD
*flags
)
492 FIXME("iface %p, id %lu, flags %p stub!\n", iface
, id
, flags
);
496 static HRESULT WINAPI
transform_GetOutputStatus(IMFTransform
*iface
, DWORD
*flags
)
498 FIXME("iface %p, flags %p stub!\n", iface
, flags
);
502 static HRESULT WINAPI
transform_SetOutputBounds(IMFTransform
*iface
, LONGLONG lower
, LONGLONG upper
)
504 FIXME("iface %p, lower %s, upper %s stub!\n", iface
, wine_dbgstr_longlong(lower
),
505 wine_dbgstr_longlong(upper
));
509 static HRESULT WINAPI
transform_ProcessEvent(IMFTransform
*iface
, DWORD id
, IMFMediaEvent
*event
)
511 FIXME("iface %p, id %lu, event %p stub!\n", iface
, id
, event
);
515 static HRESULT WINAPI
transform_ProcessMessage(IMFTransform
*iface
, MFT_MESSAGE_TYPE message
, ULONG_PTR param
)
517 FIXME("iface %p, message %#x, param %p stub!\n", iface
, message
, (void *)param
);
521 static HRESULT WINAPI
transform_ProcessInput(IMFTransform
*iface
, DWORD id
, IMFSample
*sample
, DWORD flags
)
523 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
524 struct wg_sample
*wg_sample
;
525 MFT_INPUT_STREAM_INFO info
;
528 TRACE("iface %p, id %lu, sample %p, flags %#lx.\n", iface
, id
, sample
, flags
);
530 if (!decoder
->wg_transform
)
531 return MF_E_TRANSFORM_TYPE_NOT_SET
;
533 if (FAILED(hr
= IMFTransform_GetInputStreamInfo(iface
, 0, &info
)))
536 if (FAILED(hr
= mf_create_wg_sample(sample
, &wg_sample
)))
539 /* WMA transform uses fixed size input samples and ignores samples with invalid sizes */
540 if (wg_sample
->size
% info
.cbSize
)
543 hr
= wg_transform_push_data(decoder
->wg_transform
, wg_sample
);
545 mf_destroy_wg_sample(wg_sample
);
549 static HRESULT WINAPI
transform_ProcessOutput(IMFTransform
*iface
, DWORD flags
, DWORD count
,
550 MFT_OUTPUT_DATA_BUFFER
*samples
, DWORD
*status
)
552 struct wma_decoder
*decoder
= impl_from_IMFTransform(iface
);
553 MFT_OUTPUT_STREAM_INFO info
;
554 struct wg_sample
*wg_sample
;
557 TRACE("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface
, flags
, count
, samples
, status
);
562 if (!decoder
->wg_transform
)
563 return MF_E_TRANSFORM_TYPE_NOT_SET
;
565 if (FAILED(hr
= IMFTransform_GetOutputStreamInfo(iface
, 0, &info
)))
569 samples
[0].dwStatus
= 0;
570 if (!samples
[0].pSample
)
572 samples
[0].dwStatus
= MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
;
573 return MF_E_TRANSFORM_NEED_MORE_INPUT
;
576 if (FAILED(hr
= mf_create_wg_sample(samples
[0].pSample
, &wg_sample
)))
580 if (wg_sample
->max_size
< info
.cbSize
)
581 hr
= MF_E_BUFFERTOOSMALL
;
582 else if (SUCCEEDED(hr
= wg_transform_read_data(decoder
->wg_transform
, wg_sample
)))
584 if (wg_sample
->flags
& WG_SAMPLE_FLAG_INCOMPLETE
)
585 samples
[0].dwStatus
|= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
;
588 mf_destroy_wg_sample(wg_sample
);
592 static const IMFTransformVtbl transform_vtbl
=
594 transform_QueryInterface
,
597 transform_GetStreamLimits
,
598 transform_GetStreamCount
,
599 transform_GetStreamIDs
,
600 transform_GetInputStreamInfo
,
601 transform_GetOutputStreamInfo
,
602 transform_GetAttributes
,
603 transform_GetInputStreamAttributes
,
604 transform_GetOutputStreamAttributes
,
605 transform_DeleteInputStream
,
606 transform_AddInputStreams
,
607 transform_GetInputAvailableType
,
608 transform_GetOutputAvailableType
,
609 transform_SetInputType
,
610 transform_SetOutputType
,
611 transform_GetInputCurrentType
,
612 transform_GetOutputCurrentType
,
613 transform_GetInputStatus
,
614 transform_GetOutputStatus
,
615 transform_SetOutputBounds
,
616 transform_ProcessEvent
,
617 transform_ProcessMessage
,
618 transform_ProcessInput
,
619 transform_ProcessOutput
,
622 static inline struct wma_decoder
*impl_from_IMediaObject(IMediaObject
*iface
)
624 return CONTAINING_RECORD(iface
, struct wma_decoder
, IMediaObject_iface
);
627 static HRESULT WINAPI
media_object_QueryInterface(IMediaObject
*iface
, REFIID iid
, void **obj
)
629 struct wma_decoder
*decoder
= impl_from_IMediaObject(iface
);
630 return IUnknown_QueryInterface(decoder
->outer
, iid
, obj
);
633 static ULONG WINAPI
media_object_AddRef(IMediaObject
*iface
)
635 struct wma_decoder
*decoder
= impl_from_IMediaObject(iface
);
636 return IUnknown_AddRef(decoder
->outer
);
639 static ULONG WINAPI
media_object_Release(IMediaObject
*iface
)
641 struct wma_decoder
*decoder
= impl_from_IMediaObject(iface
);
642 return IUnknown_Release(decoder
->outer
);
645 static HRESULT WINAPI
media_object_GetStreamCount(IMediaObject
*iface
, DWORD
*input
, DWORD
*output
)
647 FIXME("iface %p, input %p, output %p semi-stub!\n", iface
, input
, output
);
648 *input
= *output
= 1;
652 static HRESULT WINAPI
media_object_GetInputStreamInfo(IMediaObject
*iface
, DWORD index
, DWORD
*flags
)
654 FIXME("iface %p, index %lu, flags %p stub!\n", iface
, index
, flags
);
658 static HRESULT WINAPI
media_object_GetOutputStreamInfo(IMediaObject
*iface
, DWORD index
, DWORD
*flags
)
660 FIXME("iface %p, index %lu, flags %p stub!\n", iface
, index
, flags
);
664 static HRESULT WINAPI
media_object_GetInputType(IMediaObject
*iface
, DWORD index
, DWORD type_index
,
665 DMO_MEDIA_TYPE
*type
)
667 FIXME("iface %p, index %lu, type_index %lu, type %p stub!\n", iface
, index
, type_index
, type
);
671 static HRESULT WINAPI
media_object_GetOutputType(IMediaObject
*iface
, DWORD index
, DWORD type_index
,
672 DMO_MEDIA_TYPE
*type
)
674 FIXME("iface %p, index %lu, type_index %lu, type %p stub!\n", iface
, index
, type_index
, type
);
678 static HRESULT WINAPI
media_object_SetInputType(IMediaObject
*iface
, DWORD index
,
679 const DMO_MEDIA_TYPE
*type
, DWORD flags
)
681 FIXME("iface %p, index %lu, type %p, flags %#lx stub!\n", iface
, index
, type
, flags
);
685 static HRESULT WINAPI
media_object_SetOutputType(IMediaObject
*iface
, DWORD index
,
686 const DMO_MEDIA_TYPE
*type
, DWORD flags
)
688 FIXME("iface %p, index %lu, type %p, flags %#lx stub!\n", iface
, index
, type
, flags
);
692 static HRESULT WINAPI
media_object_GetInputCurrentType(IMediaObject
*iface
, DWORD index
, DMO_MEDIA_TYPE
*type
)
694 FIXME("iface %p, index %lu, type %p stub!\n", iface
, index
, type
);
698 static HRESULT WINAPI
media_object_GetOutputCurrentType(IMediaObject
*iface
, DWORD index
, DMO_MEDIA_TYPE
*type
)
700 FIXME("iface %p, index %lu, type %p stub!\n", iface
, index
, type
);
704 static HRESULT WINAPI
media_object_GetInputSizeInfo(IMediaObject
*iface
, DWORD index
, DWORD
*size
,
705 DWORD
*lookahead
, DWORD
*alignment
)
707 FIXME("iface %p, index %lu, size %p, lookahead %p, alignment %p stub!\n", iface
, index
, size
,
708 lookahead
, alignment
);
712 static HRESULT WINAPI
media_object_GetOutputSizeInfo(IMediaObject
*iface
, DWORD index
, DWORD
*size
, DWORD
*alignment
)
714 FIXME("iface %p, index %lu, size %p, alignment %p stub!\n", iface
, index
, size
, alignment
);
718 static HRESULT WINAPI
media_object_GetInputMaxLatency(IMediaObject
*iface
, DWORD index
, REFERENCE_TIME
*latency
)
720 FIXME("iface %p, index %lu, latency %p stub!\n", iface
, index
, latency
);
724 static HRESULT WINAPI
media_object_SetInputMaxLatency(IMediaObject
*iface
, DWORD index
, REFERENCE_TIME latency
)
726 FIXME("iface %p, index %lu, latency %s stub!\n", iface
, index
, wine_dbgstr_longlong(latency
));
730 static HRESULT WINAPI
media_object_Flush(IMediaObject
*iface
)
732 FIXME("iface %p stub!\n", iface
);
736 static HRESULT WINAPI
media_object_Discontinuity(IMediaObject
*iface
, DWORD index
)
738 FIXME("iface %p, index %lu stub!\n", iface
, index
);
742 static HRESULT WINAPI
media_object_AllocateStreamingResources(IMediaObject
*iface
)
744 FIXME("iface %p stub!\n", iface
);
748 static HRESULT WINAPI
media_object_FreeStreamingResources(IMediaObject
*iface
)
750 FIXME("iface %p stub!\n", iface
);
754 static HRESULT WINAPI
media_object_GetInputStatus(IMediaObject
*iface
, DWORD index
, DWORD
*flags
)
756 FIXME("iface %p, index %lu, flags %p stub!\n", iface
, index
, flags
);
760 static HRESULT WINAPI
media_object_ProcessInput(IMediaObject
*iface
, DWORD index
,
761 IMediaBuffer
*buffer
, DWORD flags
, REFERENCE_TIME timestamp
, REFERENCE_TIME timelength
)
763 FIXME("iface %p, index %lu, buffer %p, flags %#lx, timestamp %s, timelength %s stub!\n", iface
,
764 index
, buffer
, flags
, wine_dbgstr_longlong(timestamp
), wine_dbgstr_longlong(timelength
));
768 static HRESULT WINAPI
media_object_ProcessOutput(IMediaObject
*iface
, DWORD flags
, DWORD count
,
769 DMO_OUTPUT_DATA_BUFFER
*buffers
, DWORD
*status
)
771 FIXME("iface %p, flags %#lx, count %lu, buffers %p, status %p stub!\n", iface
, flags
, count
, buffers
, status
);
775 static HRESULT WINAPI
media_object_Lock(IMediaObject
*iface
, LONG lock
)
777 FIXME("iface %p, lock %ld stub!\n", iface
, lock
);
781 static const IMediaObjectVtbl media_object_vtbl
=
783 media_object_QueryInterface
,
785 media_object_Release
,
786 media_object_GetStreamCount
,
787 media_object_GetInputStreamInfo
,
788 media_object_GetOutputStreamInfo
,
789 media_object_GetInputType
,
790 media_object_GetOutputType
,
791 media_object_SetInputType
,
792 media_object_SetOutputType
,
793 media_object_GetInputCurrentType
,
794 media_object_GetOutputCurrentType
,
795 media_object_GetInputSizeInfo
,
796 media_object_GetOutputSizeInfo
,
797 media_object_GetInputMaxLatency
,
798 media_object_SetInputMaxLatency
,
800 media_object_Discontinuity
,
801 media_object_AllocateStreamingResources
,
802 media_object_FreeStreamingResources
,
803 media_object_GetInputStatus
,
804 media_object_ProcessInput
,
805 media_object_ProcessOutput
,
809 static inline struct wma_decoder
*impl_from_IPropertyBag(IPropertyBag
*iface
)
811 return CONTAINING_RECORD(iface
, struct wma_decoder
, IPropertyBag_iface
);
814 static HRESULT WINAPI
property_bag_QueryInterface(IPropertyBag
*iface
, REFIID iid
, void **out
)
816 struct wma_decoder
*filter
= impl_from_IPropertyBag(iface
);
817 return IUnknown_QueryInterface(filter
->outer
, iid
, out
);
820 static ULONG WINAPI
property_bag_AddRef(IPropertyBag
*iface
)
822 struct wma_decoder
*filter
= impl_from_IPropertyBag(iface
);
823 return IUnknown_AddRef(filter
->outer
);
826 static ULONG WINAPI
property_bag_Release(IPropertyBag
*iface
)
828 struct wma_decoder
*filter
= impl_from_IPropertyBag(iface
);
829 return IUnknown_Release(filter
->outer
);
832 static HRESULT WINAPI
property_bag_Read(IPropertyBag
*iface
, const WCHAR
*prop_name
, VARIANT
*value
,
833 IErrorLog
*error_log
)
835 FIXME("iface %p, prop_name %s, value %p, error_log %p stub!\n", iface
, debugstr_w(prop_name
), value
, error_log
);
839 static HRESULT WINAPI
property_bag_Write(IPropertyBag
*iface
, const WCHAR
*prop_name
, VARIANT
*value
)
841 FIXME("iface %p, prop_name %s, value %p stub!\n", iface
, debugstr_w(prop_name
), value
);
845 static const IPropertyBagVtbl property_bag_vtbl
=
847 property_bag_QueryInterface
,
849 property_bag_Release
,
854 HRESULT
wma_decoder_create(IUnknown
*outer
, IUnknown
**out
)
856 struct wma_decoder
*decoder
;
858 TRACE("outer %p, out %p.\n", outer
, out
);
860 if (!(decoder
= calloc(1, sizeof(*decoder
))))
861 return E_OUTOFMEMORY
;
863 decoder
->IUnknown_inner
.lpVtbl
= &unknown_vtbl
;
864 decoder
->IMFTransform_iface
.lpVtbl
= &transform_vtbl
;
865 decoder
->IMediaObject_iface
.lpVtbl
= &media_object_vtbl
;
866 decoder
->IPropertyBag_iface
.lpVtbl
= &property_bag_vtbl
;
867 decoder
->refcount
= 1;
868 decoder
->outer
= outer
? outer
: &decoder
->IUnknown_inner
;
870 *out
= &decoder
->IUnknown_inner
;
871 TRACE("Created decoder %p\n", *out
);