mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 05:49:49 +00:00
winegstreamer: Try creating a wg_transform in the H264 decoder.
Adding H264 format support in wg_format. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
962b4325e5
commit
606505e564
|
@ -48,6 +48,8 @@ struct h264_decoder
|
|||
LONG refcount;
|
||||
IMFMediaType *input_type;
|
||||
IMFMediaType *output_type;
|
||||
|
||||
struct wg_transform *wg_transform;
|
||||
};
|
||||
|
||||
static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface)
|
||||
|
@ -55,6 +57,29 @@ static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface)
|
|||
return CONTAINING_RECORD(iface, struct h264_decoder, IMFTransform_iface);
|
||||
}
|
||||
|
||||
static HRESULT try_create_wg_transform(struct h264_decoder *decoder)
|
||||
{
|
||||
struct wg_format input_format;
|
||||
struct wg_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 fill_output_media_type(IMFMediaType *media_type, IMFMediaType *default_type)
|
||||
{
|
||||
UINT32 value, width, height;
|
||||
|
@ -183,6 +208,8 @@ static ULONG WINAPI transform_Release(IMFTransform *iface)
|
|||
|
||||
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)
|
||||
|
@ -416,7 +443,13 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
|
|||
IMFMediaType_Release(decoder->output_type);
|
||||
IMFMediaType_AddRef((decoder->output_type = type));
|
||||
|
||||
return S_OK;
|
||||
if (FAILED(hr = try_create_wg_transform(decoder)))
|
||||
{
|
||||
IMFMediaType_Release(decoder->output_type);
|
||||
decoder->output_type = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI transform_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
|
|
|
@ -659,11 +659,11 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format)
|
|||
{
|
||||
switch (format->major_type)
|
||||
{
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
return NULL;
|
||||
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
FIXME("WMA format not implemented!\n");
|
||||
FIXME("Format %u not implemented!\n", format->major_type);
|
||||
/* fallthrough */
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
return NULL;
|
||||
|
||||
case WG_MAJOR_TYPE_AUDIO:
|
||||
|
@ -822,6 +822,38 @@ static void mf_media_type_to_wg_format_wma(IMFMediaType *type, const GUID *subty
|
|||
memcpy(format->u.wma.codec_data, codec_data, codec_data_len);
|
||||
}
|
||||
|
||||
static void mf_media_type_to_wg_format_h264(IMFMediaType *type, struct wg_format *format)
|
||||
{
|
||||
UINT64 frame_rate, frame_size;
|
||||
UINT32 profile, level;
|
||||
|
||||
memset(format, 0, sizeof(*format));
|
||||
format->major_type = WG_MAJOR_TYPE_H264;
|
||||
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
{
|
||||
format->u.h264.width = frame_size >> 32;
|
||||
format->u.h264.height = (UINT32)frame_size;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
|
||||
{
|
||||
format->u.h264.fps_n = frame_rate >> 32;
|
||||
format->u.h264.fps_d = (UINT32)frame_rate;
|
||||
}
|
||||
else
|
||||
{
|
||||
format->u.h264.fps_n = 1;
|
||||
format->u.h264.fps_d = 1;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &profile)))
|
||||
format->u.h264.profile = profile;
|
||||
|
||||
if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &level)))
|
||||
format->u.h264.level = level;
|
||||
}
|
||||
|
||||
void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
|
||||
{
|
||||
GUID major_type, subtype;
|
||||
|
@ -850,7 +882,12 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
|
|||
mf_media_type_to_wg_format_audio(type, &subtype, format);
|
||||
}
|
||||
else if (IsEqualGUID(&major_type, &MFMediaType_Video))
|
||||
mf_media_type_to_wg_format_video(type, &subtype, format);
|
||||
{
|
||||
if (IsEqualGUID(&subtype, &MFVideoFormat_H264))
|
||||
mf_media_type_to_wg_format_h264(type, format);
|
||||
else
|
||||
mf_media_type_to_wg_format_video(type, &subtype, format);
|
||||
}
|
||||
else
|
||||
FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type));
|
||||
}
|
||||
|
|
|
@ -328,8 +328,9 @@ unsigned int wg_format_get_max_size(const struct wg_format *format)
|
|||
break;
|
||||
}
|
||||
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
FIXME("WMA format not implemented!\n");
|
||||
FIXME("Format %u not implemented!\n", format->major_type);
|
||||
return 0;
|
||||
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
|
@ -423,11 +424,11 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool
|
|||
|
||||
switch (format->major_type)
|
||||
{
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
return false;
|
||||
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
FIXME("WMA format not implemented!\n");
|
||||
FIXME("Format %u not implemented!\n", format->major_type);
|
||||
/* fallthrough */
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
return false;
|
||||
|
||||
case WG_MAJOR_TYPE_AUDIO:
|
||||
|
|
|
@ -38,6 +38,7 @@ struct wg_format
|
|||
WG_MAJOR_TYPE_VIDEO,
|
||||
WG_MAJOR_TYPE_AUDIO,
|
||||
WG_MAJOR_TYPE_WMA,
|
||||
WG_MAJOR_TYPE_H264,
|
||||
} major_type;
|
||||
|
||||
union
|
||||
|
@ -100,6 +101,13 @@ struct wg_format
|
|||
uint32_t codec_data_len;
|
||||
unsigned char codec_data[64];
|
||||
} wma;
|
||||
struct
|
||||
{
|
||||
int32_t width, height;
|
||||
uint32_t fps_n, fps_d;
|
||||
uint32_t profile;
|
||||
uint32_t level;
|
||||
} h264;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <gst/audio/audio.h>
|
||||
|
||||
#include "winternl.h"
|
||||
#include "codecapi.h"
|
||||
#include "dshow.h"
|
||||
|
||||
#include "unix_private.h"
|
||||
|
@ -431,6 +432,64 @@ static GstCaps *wg_format_to_caps_wma(const struct wg_format *format)
|
|||
return caps;
|
||||
}
|
||||
|
||||
static GstCaps *wg_format_to_caps_h264(const struct wg_format *format)
|
||||
{
|
||||
const char *profile, *level;
|
||||
GstCaps *caps;
|
||||
|
||||
caps = gst_caps_new_empty_simple("video/x-h264");
|
||||
gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL);
|
||||
gst_caps_set_simple(caps, "alignment", G_TYPE_STRING, "au", NULL);
|
||||
|
||||
if (format->u.h264.width)
|
||||
gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.h264.width, NULL);
|
||||
if (format->u.h264.height)
|
||||
gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.h264.height, NULL);
|
||||
if (format->u.h264.fps_n || format->u.h264.fps_d)
|
||||
gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.h264.fps_n, format->u.h264.fps_d, NULL);
|
||||
|
||||
switch (format->u.h264.profile)
|
||||
{
|
||||
case eAVEncH264VProfile_Main: profile = "main"; break;
|
||||
case eAVEncH264VProfile_High: profile = "high"; break;
|
||||
case eAVEncH264VProfile_444: profile = "high-4:4:4"; break;
|
||||
default:
|
||||
GST_FIXME("H264 profile attribute %u not implemented.", format->u.h264.profile);
|
||||
profile = NULL;
|
||||
break;
|
||||
}
|
||||
if (profile)
|
||||
gst_caps_set_simple(caps, "profile", G_TYPE_STRING, profile, NULL);
|
||||
|
||||
switch (format->u.h264.level)
|
||||
{
|
||||
case eAVEncH264VLevel1: level = "1"; break;
|
||||
case eAVEncH264VLevel1_1: level = "1.1"; break;
|
||||
case eAVEncH264VLevel1_2: level = "1.2"; break;
|
||||
case eAVEncH264VLevel1_3: level = "1.3"; break;
|
||||
case eAVEncH264VLevel2: level = "2"; break;
|
||||
case eAVEncH264VLevel2_1: level = "2.1"; break;
|
||||
case eAVEncH264VLevel2_2: level = "2.2"; break;
|
||||
case eAVEncH264VLevel3: level = "3"; break;
|
||||
case eAVEncH264VLevel3_1: level = "3.1"; break;
|
||||
case eAVEncH264VLevel3_2: level = "3.2"; break;
|
||||
case eAVEncH264VLevel4: level = "4"; break;
|
||||
case eAVEncH264VLevel4_1: level = "4.1"; break;
|
||||
case eAVEncH264VLevel4_2: level = "4.2"; break;
|
||||
case eAVEncH264VLevel5: level = "5"; break;
|
||||
case eAVEncH264VLevel5_1: level = "5.1"; break;
|
||||
case eAVEncH264VLevel5_2: level = "5.2"; break;
|
||||
default:
|
||||
GST_FIXME("H264 level attribute %u not implemented.", format->u.h264.level);
|
||||
level = NULL;
|
||||
break;
|
||||
}
|
||||
if (level)
|
||||
gst_caps_set_simple(caps, "level", G_TYPE_STRING, level, NULL);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
GstCaps *wg_format_to_caps(const struct wg_format *format)
|
||||
{
|
||||
switch (format->major_type)
|
||||
|
@ -439,6 +498,8 @@ GstCaps *wg_format_to_caps(const struct wg_format *format)
|
|||
return NULL;
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
return wg_format_to_caps_wma(format);
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
return wg_format_to_caps_h264(format);
|
||||
case WG_MAJOR_TYPE_AUDIO:
|
||||
return wg_format_to_caps_audio(format);
|
||||
case WG_MAJOR_TYPE_VIDEO:
|
||||
|
@ -455,11 +516,11 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b)
|
|||
|
||||
switch (a->major_type)
|
||||
{
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
return false;
|
||||
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
GST_FIXME("WMA format not implemented!\n");
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
GST_FIXME("Format %u not implemented!", a->major_type);
|
||||
/* fallthrough */
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
return false;
|
||||
|
||||
case WG_MAJOR_TYPE_AUDIO:
|
||||
|
|
|
@ -211,6 +211,7 @@ NTSTATUS wg_transform_create(void *args)
|
|||
|
||||
switch (input_format.major_type)
|
||||
{
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
if (!(element = transform_find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, src_caps, raw_caps))
|
||||
|| !transform_append_element(transform, element, &first, &last))
|
||||
|
@ -251,6 +252,9 @@ NTSTATUS wg_transform_create(void *args)
|
|||
break;
|
||||
|
||||
case WG_MAJOR_TYPE_VIDEO:
|
||||
break;
|
||||
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
GST_FIXME("Format %u not implemented!", output_format.major_type);
|
||||
|
|
|
@ -1687,7 +1687,8 @@ HRESULT wm_reader_get_output_format_count(struct wm_reader *reader, DWORD output
|
|||
break;
|
||||
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
FIXME("WMA format not implemented!\n");
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
FIXME("Format %u not implemented!\n", format.major_type);
|
||||
/* fallthrough */
|
||||
case WG_MAJOR_TYPE_AUDIO:
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
|
@ -1736,7 +1737,8 @@ HRESULT wm_reader_get_output_format(struct wm_reader *reader, DWORD output,
|
|||
break;
|
||||
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
FIXME("WMA format not implemented!\n");
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
FIXME("Format %u not implemented!\n", format.major_type);
|
||||
break;
|
||||
case WG_MAJOR_TYPE_UNKNOWN:
|
||||
break;
|
||||
|
@ -1815,6 +1817,8 @@ static const char *get_major_type_string(enum wg_major_type type)
|
|||
return "unknown";
|
||||
case WG_MAJOR_TYPE_WMA:
|
||||
return "wma";
|
||||
case WG_MAJOR_TYPE_H264:
|
||||
return "h264";
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in a new issue