mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-22 00:24:09 +00:00
winegstreamer: Use an IMFMediaType for the internal stream type.
This commit is contained in:
parent
6184ac8c9f
commit
8caaca177e
|
@ -57,8 +57,8 @@ struct h264_decoder
|
|||
MFT_INPUT_STREAM_INFO input_info;
|
||||
IMFMediaType *output_type;
|
||||
MFT_OUTPUT_STREAM_INFO output_info;
|
||||
IMFMediaType *stream_type;
|
||||
|
||||
struct wg_format wg_format;
|
||||
struct wg_transform *wg_transform;
|
||||
struct wg_sample_queue *wg_sample_queue;
|
||||
|
||||
|
@ -107,8 +107,8 @@ static HRESULT try_create_wg_transform(struct h264_decoder *decoder)
|
|||
static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType *media_type)
|
||||
{
|
||||
IMFMediaType *default_type = decoder->output_type;
|
||||
struct wg_format *wg_format = &decoder->wg_format;
|
||||
UINT32 value, width, height;
|
||||
MFVideoArea aperture;
|
||||
UINT64 ratio;
|
||||
GUID subtype;
|
||||
HRESULT hr;
|
||||
|
@ -118,7 +118,8 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType
|
|||
|
||||
if (FAILED(hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &ratio)))
|
||||
{
|
||||
ratio = (UINT64)wg_format->u.video.width << 32 | wg_format->u.video.height;
|
||||
if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &ratio)))
|
||||
ratio = (UINT64)1920 << 32 | 1080;
|
||||
if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ratio)))
|
||||
return hr;
|
||||
}
|
||||
|
@ -127,14 +128,16 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType
|
|||
|
||||
if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FRAME_RATE, NULL)))
|
||||
{
|
||||
ratio = (UINT64)wg_format->u.video.fps_n << 32 | wg_format->u.video.fps_d;
|
||||
if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, &ratio)))
|
||||
ratio = (UINT64)30000 << 32 | 1001;
|
||||
if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ratio)))
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL)))
|
||||
{
|
||||
ratio = (UINT64)1 << 32 | 1; /* FIXME: read it from format */
|
||||
if (FAILED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio)))
|
||||
ratio = (UINT64)1 << 32 | 1;
|
||||
if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio)))
|
||||
return hr;
|
||||
}
|
||||
|
@ -188,17 +191,9 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType
|
|||
}
|
||||
|
||||
if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL))
|
||||
&& (wg_format->u.video.padding.left || wg_format->u.video.padding.right || wg_format->u.video.padding.top
|
||||
|| wg_format->u.video.padding.bottom))
|
||||
&& SUCCEEDED(hr = IMFMediaType_GetBlob(decoder->stream_type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
|
||||
(BYTE *)&aperture, sizeof(aperture), &value)))
|
||||
{
|
||||
MFVideoArea aperture =
|
||||
{
|
||||
.OffsetX = {.value = wg_format->u.video.padding.left},
|
||||
.OffsetY = {.value = wg_format->u.video.padding.top},
|
||||
.Area.cx = wg_format->u.video.width - wg_format->u.video.padding.right - wg_format->u.video.padding.left,
|
||||
.Area.cy = wg_format->u.video.height - wg_format->u.video.padding.bottom - wg_format->u.video.padding.top,
|
||||
};
|
||||
|
||||
if (FAILED(hr = IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
|
||||
(BYTE *)&aperture, sizeof(aperture))))
|
||||
return hr;
|
||||
|
@ -482,10 +477,9 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
|
|||
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
{
|
||||
decoder->wg_format.u.video.width = frame_size >> 32;
|
||||
decoder->wg_format.u.video.height = (UINT32)frame_size;
|
||||
decoder->output_info.cbSize = decoder->wg_format.u.video.width
|
||||
* decoder->wg_format.u.video.height * 2;
|
||||
if (FAILED(hr = IMFMediaType_SetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, frame_size)))
|
||||
WARN("Failed to update stream type frame size, hr %#lx\n", hr);
|
||||
decoder->output_info.cbSize = (frame_size >> 32) * (UINT32)frame_size * 2;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -494,8 +488,8 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
|
|||
static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
struct h264_decoder *decoder = impl_from_IMFTransform(iface);
|
||||
UINT64 frame_size, stream_frame_size;
|
||||
GUID major, subtype;
|
||||
UINT64 frame_size;
|
||||
HRESULT hr;
|
||||
ULONG i;
|
||||
|
||||
|
@ -517,9 +511,10 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
|
|||
if (i == ARRAY_SIZE(h264_decoder_output_types))
|
||||
return MF_E_INVALIDMEDIATYPE;
|
||||
|
||||
if (FAILED(hr = IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))
|
||||
|| (frame_size >> 32) != decoder->wg_format.u.video.width
|
||||
|| (UINT32)frame_size != decoder->wg_format.u.video.height)
|
||||
if (FAILED(hr = IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
return MF_E_INVALIDMEDIATYPE;
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &stream_frame_size))
|
||||
&& frame_size != stream_frame_size)
|
||||
return MF_E_INVALIDMEDIATYPE;
|
||||
if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
return S_OK;
|
||||
|
@ -677,6 +672,28 @@ static HRESULT output_sample(struct h264_decoder *decoder, IMFSample **out, IMFS
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT handle_stream_type_change(struct h264_decoder *decoder, const struct wg_format *format)
|
||||
{
|
||||
UINT64 frame_size, frame_rate;
|
||||
HRESULT hr;
|
||||
|
||||
if (decoder->stream_type)
|
||||
IMFMediaType_Release(decoder->stream_type);
|
||||
if (!(decoder->stream_type = mf_media_type_from_wg_format(format)))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_RATE, &frame_rate))
|
||||
&& FAILED(hr = IMFMediaType_SetUINT64(decoder->stream_type, &MF_MT_FRAME_RATE, frame_rate)))
|
||||
WARN("Failed to update stream type frame size, hr %#lx\n", hr);
|
||||
|
||||
if (FAILED(hr = IMFMediaType_GetUINT64(decoder->stream_type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
return hr;
|
||||
decoder->output_info.cbSize = (frame_size >> 32) * (UINT32)frame_size * 2;
|
||||
uninit_allocator(decoder);
|
||||
|
||||
return MF_E_TRANSFORM_STREAM_CHANGE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
|
||||
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
|
||||
{
|
||||
|
@ -684,7 +701,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
struct wg_format wg_format;
|
||||
UINT32 sample_size;
|
||||
IMFSample *sample;
|
||||
UINT64 frame_rate;
|
||||
UINT64 frame_size;
|
||||
GUID subtype;
|
||||
DWORD size;
|
||||
HRESULT hr;
|
||||
|
@ -703,8 +720,9 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
|
||||
if (FAILED(hr = IMFMediaType_GetGUID(decoder->output_type, &MF_MT_SUBTYPE, &subtype)))
|
||||
return hr;
|
||||
if (FAILED(hr = MFCalculateImageSize(&subtype, decoder->wg_format.u.video.width,
|
||||
decoder->wg_format.u.video.height, &sample_size)))
|
||||
if (FAILED(hr = IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
return hr;
|
||||
if (FAILED(hr = MFCalculateImageSize(&subtype, frame_size >> 32, (UINT32)frame_size, &sample_size)))
|
||||
return hr;
|
||||
|
||||
if (decoder->output_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES)
|
||||
|
@ -734,21 +752,9 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
|
|||
|
||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
|
||||
{
|
||||
decoder->wg_format = wg_format;
|
||||
decoder->output_info.cbSize = ALIGN_SIZE(decoder->wg_format.u.video.width, 0xf)
|
||||
* ALIGN_SIZE(decoder->wg_format.u.video.height, 0xf) * 2;
|
||||
|
||||
/* keep the frame rate that was requested, GStreamer doesn't provide any */
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_RATE, &frame_rate)))
|
||||
{
|
||||
decoder->wg_format.u.video.fps_n = frame_rate >> 32;
|
||||
decoder->wg_format.u.video.fps_d = (UINT32)frame_rate;
|
||||
}
|
||||
|
||||
samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
|
||||
*status |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
|
||||
|
||||
uninit_allocator(decoder);
|
||||
hr = handle_stream_type_change(decoder, &wg_format);
|
||||
}
|
||||
|
||||
if (decoder->output_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES)
|
||||
|
@ -822,11 +828,6 @@ HRESULT h264_decoder_create(REFIID riid, void **ret)
|
|||
|
||||
decoder->IMFTransform_iface.lpVtbl = &transform_vtbl;
|
||||
decoder->refcount = 1;
|
||||
decoder->wg_format.u.video.format = WG_VIDEO_FORMAT_UNKNOWN;
|
||||
decoder->wg_format.u.video.width = 1920;
|
||||
decoder->wg_format.u.video.height = 1080;
|
||||
decoder->wg_format.u.video.fps_n = 30000;
|
||||
decoder->wg_format.u.video.fps_d = 1001;
|
||||
|
||||
decoder->input_info.dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
||||
| MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE;
|
||||
|
@ -835,6 +836,8 @@ HRESULT h264_decoder_create(REFIID riid, void **ret)
|
|||
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;
|
||||
decoder->output_info.cbSize = 1920 * 1088 * 2;
|
||||
|
||||
if (FAILED(hr = MFCreateMediaType(&decoder->stream_type)))
|
||||
goto failed;
|
||||
if (FAILED(hr = MFCreateAttributes(&decoder->attributes, 16)))
|
||||
goto failed;
|
||||
if (FAILED(hr = IMFAttributes_SetUINT32(decoder->attributes, &MF_LOW_LATENCY, 0)))
|
||||
|
@ -863,6 +866,8 @@ failed:
|
|||
IMFAttributes_Release(decoder->output_attributes);
|
||||
if (decoder->attributes)
|
||||
IMFAttributes_Release(decoder->attributes);
|
||||
if (decoder->stream_type)
|
||||
IMFMediaType_Release(decoder->stream_type);
|
||||
free(decoder);
|
||||
return hr;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue