Skip to content

Commit 0906f69

Browse files
rbernonjulliard
authored andcommitted
winegstreamer: Translate MFVIDEOFORMAT / WAVEFORMATEX directly to GstCaps in wg_transform.
1 parent fbceb9e commit 0906f69

File tree

8 files changed

+476
-37
lines changed

8 files changed

+476
-37
lines changed

dlls/winegstreamer/gst_private.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ HRESULT wg_transform_create_quartz(const AM_MEDIA_TYPE *input_format, const AM_M
8989
const struct wg_transform_attrs *attrs, wg_transform_t *transform);
9090
void wg_transform_destroy(wg_transform_t transform);
9191
HRESULT wg_transform_get_output_type(wg_transform_t transform, IMFMediaType **media_type);
92-
bool wg_transform_set_output_format(wg_transform_t transform, struct wg_format *format);
92+
HRESULT wg_transform_set_output_type(wg_transform_t transform, IMFMediaType *media_type);
9393
bool wg_transform_get_status(wg_transform_t transform, bool *accepts_input);
9494
HRESULT wg_transform_drain(wg_transform_t transform);
9595
HRESULT wg_transform_flush(wg_transform_t transform);

dlls/winegstreamer/main.c

+78-5
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,66 @@ bool array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
7070
return TRUE;
7171
}
7272

73+
static HRESULT video_format_from_media_type(IMFMediaType *media_type, MFVIDEOFORMAT **format, UINT32 *format_size)
74+
{
75+
GUID subtype;
76+
HRESULT hr;
77+
78+
if (FAILED(hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype)))
79+
return hr;
80+
if (FAILED(hr = MFCreateMFVideoFormatFromMFMediaType(media_type, format, format_size)))
81+
return hr;
82+
83+
/* fixup MPEG video formats here, so we can consistently use MFVIDEOFORMAT internally */
84+
if (IsEqualGUID(&subtype, &MEDIASUBTYPE_MPEG1Payload)
85+
|| IsEqualGUID(&subtype, &MEDIASUBTYPE_MPEG1Packet)
86+
|| IsEqualGUID(&subtype, &MEDIASUBTYPE_MPEG2_VIDEO))
87+
{
88+
struct mpeg_video_format *mpeg;
89+
UINT32 mpeg_size, len;
90+
91+
if (FAILED(IMFMediaType_GetBlobSize(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, &len)))
92+
len = 0;
93+
mpeg_size = offsetof(struct mpeg_video_format, sequence_header[len]);
94+
95+
if ((mpeg = CoTaskMemAlloc(mpeg_size)))
96+
{
97+
memset(mpeg, 0, mpeg_size);
98+
mpeg->hdr = **format;
99+
100+
IMFMediaType_GetBlob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, mpeg->sequence_header, len, NULL);
101+
IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG_START_TIME_CODE, (UINT32 *)&mpeg->start_time_code);
102+
IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_PROFILE, &mpeg->profile);
103+
IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_LEVEL, &mpeg->level);
104+
IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_FLAGS, &mpeg->flags);
105+
106+
CoTaskMemFree(*format);
107+
*format = &mpeg->hdr;
108+
*format_size = mpeg_size;
109+
}
110+
}
111+
112+
return hr;
113+
}
114+
115+
static HRESULT wg_media_type_from_mf(IMFMediaType *media_type, struct wg_media_type *wg_media_type)
116+
{
117+
HRESULT hr;
118+
119+
if (FAILED(hr = IMFMediaType_GetMajorType(media_type, &wg_media_type->major)))
120+
return hr;
121+
122+
if (IsEqualGUID(&wg_media_type->major, &MFMediaType_Video))
123+
return video_format_from_media_type(media_type, &wg_media_type->u.video,
124+
&wg_media_type->format_size);
125+
if (IsEqualGUID(&wg_media_type->major, &MFMediaType_Audio))
126+
return MFCreateWaveFormatExFromMFMediaType(media_type, &wg_media_type->u.audio,
127+
&wg_media_type->format_size, 0);
128+
129+
FIXME("Unsupported major type %s\n", debugstr_guid(&wg_media_type->major));
130+
return E_NOTIMPL;
131+
}
132+
73133
static HRESULT media_type_from_video_format(const MFVIDEOFORMAT *format, IMFMediaType **media_type)
74134
{
75135
HRESULT hr;
@@ -514,17 +574,30 @@ HRESULT wg_transform_get_output_type(wg_transform_t transform, IMFMediaType **me
514574
return hr;
515575
}
516576

517-
bool wg_transform_set_output_format(wg_transform_t transform, struct wg_format *format)
577+
HRESULT wg_transform_set_output_type(wg_transform_t transform, IMFMediaType *media_type)
518578
{
519-
struct wg_transform_set_output_format_params params =
579+
struct wg_transform_set_output_type_params params =
520580
{
521581
.transform = transform,
522-
.format = format,
523582
};
583+
NTSTATUS status;
584+
HRESULT hr;
524585

525-
TRACE("transform %#I64x, format %p.\n", transform, format);
586+
TRACE("transform %#I64x, media_type %p.\n", transform, media_type);
526587

527-
return !WINE_UNIX_CALL(unix_wg_transform_set_output_format, &params);
588+
if (FAILED(hr = wg_media_type_from_mf(media_type, &params.media_type)))
589+
{
590+
WARN("Failed to initialize media type, hr %#lx\n", hr);
591+
return hr;
592+
}
593+
if ((status = WINE_UNIX_CALL(unix_wg_transform_set_output_type, &params)))
594+
{
595+
WARN("Failed to set transform output type, status %#lx\n", status);
596+
hr = HRESULT_FROM_NT(status);
597+
}
598+
599+
CoTaskMemFree(params.media_type.u.format);
600+
return hr;
528601
}
529602

530603
HRESULT wg_transform_drain(wg_transform_t transform)

dlls/winegstreamer/unix_private.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extern uint32_t wg_channel_mask_from_gst(const GstAudioInfo *info);
5959
extern NTSTATUS wg_transform_create(void *args);
6060
extern NTSTATUS wg_transform_destroy(void *args);
6161
extern NTSTATUS wg_transform_get_output_type(void *args);
62-
extern NTSTATUS wg_transform_set_output_format(void *args);
62+
extern NTSTATUS wg_transform_set_output_type(void *args);
6363
extern NTSTATUS wg_transform_push_data(void *args);
6464
extern NTSTATUS wg_transform_read_data(void *args);
6565
extern NTSTATUS wg_transform_get_status(void *args);
@@ -69,6 +69,7 @@ extern NTSTATUS wg_transform_notify_qos(void *args);
6969

7070
/* wg_media_type.c */
7171

72+
extern GstCaps *caps_from_media_type(const struct wg_media_type *media_type);
7273
extern NTSTATUS caps_to_media_type(GstCaps *caps, struct wg_media_type *media_type,
7374
UINT32 video_plane_align);
7475

dlls/winegstreamer/unixlib.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -365,10 +365,10 @@ struct wg_transform_get_output_type_params
365365
struct wg_media_type media_type;
366366
};
367367

368-
struct wg_transform_set_output_format_params
368+
struct wg_transform_set_output_type_params
369369
{
370370
wg_transform_t transform;
371-
const struct wg_format *format;
371+
struct wg_media_type media_type;
372372
};
373373

374374
struct wg_transform_get_status_params
@@ -447,7 +447,7 @@ enum unix_funcs
447447
unix_wg_transform_create,
448448
unix_wg_transform_destroy,
449449
unix_wg_transform_get_output_type,
450-
unix_wg_transform_set_output_format,
450+
unix_wg_transform_set_output_type,
451451

452452
unix_wg_transform_push_data,
453453
unix_wg_transform_read_data,

dlls/winegstreamer/video_decoder.c

+6-14
Original file line numberDiff line numberDiff line change
@@ -694,25 +694,17 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
694694
}
695695

696696
if (decoder->wg_transform)
697-
{
698-
struct wg_format output_format;
699-
mf_media_type_to_wg_format(output_type, &output_format);
697+
hr = wg_transform_set_output_type(decoder->wg_transform, output_type);
698+
else
699+
hr = try_create_wg_transform(decoder, output_type);
700700

701-
if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN
702-
|| !wg_transform_set_output_format(decoder->wg_transform, &output_format))
703-
{
704-
IMFMediaType_Release(decoder->output_type);
705-
decoder->output_type = NULL;
706-
hr = MF_E_INVALIDMEDIATYPE;
707-
}
708-
}
709-
else if (FAILED(hr = try_create_wg_transform(decoder, output_type)))
701+
IMFMediaType_Release(output_type);
702+
703+
if (FAILED(hr))
710704
{
711705
IMFMediaType_Release(decoder->output_type);
712706
decoder->output_type = NULL;
713707
}
714-
715-
IMFMediaType_Release(output_type);
716708
return hr;
717709
}
718710

0 commit comments

Comments
 (0)