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
481fd0ec
Commit
481fd0ec
authored
Oct 20, 2023
by
Alfred Agrell
Committed by
Alexandre Julliard
Nov 01, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winegstreamer: Implement CLSID_CMpegVideoCodec.
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=9127
parent
e8e5e8b5
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
195 additions
and
1 deletion
+195
-1
gst_private.h
dlls/winegstreamer/gst_private.h
+2
-0
main.c
dlls/winegstreamer/main.c
+38
-0
quartz_parser.c
dlls/winegstreamer/quartz_parser.c
+6
-0
quartz_transform.c
dlls/winegstreamer/quartz_transform.c
+141
-0
wg_transform.c
dlls/winegstreamer/wg_transform.c
+1
-1
winegstreamer_classes.idl
dlls/winegstreamer/winegstreamer_classes.idl
+7
-0
No files found.
dlls/winegstreamer/gst_private.h
View file @
481fd0ec
...
...
@@ -114,11 +114,13 @@ HRESULT wg_muxer_create(const char *format, wg_muxer_t *muxer);
void
wg_muxer_destroy
(
wg_muxer_t
muxer
);
HRESULT
wg_muxer_add_stream
(
wg_muxer_t
muxer
,
UINT32
stream_id
,
const
struct
wg_format
*
format
);
unsigned
int
wg_format_get_bytes_for_uncompressed
(
wg_video_format
format
,
unsigned
int
width
,
unsigned
int
height
);
unsigned
int
wg_format_get_max_size
(
const
struct
wg_format
*
format
);
HRESULT
avi_splitter_create
(
IUnknown
*
outer
,
IUnknown
**
out
);
HRESULT
decodebin_parser_create
(
IUnknown
*
outer
,
IUnknown
**
out
);
HRESULT
mpeg_audio_codec_create
(
IUnknown
*
outer
,
IUnknown
**
out
);
HRESULT
mpeg_video_codec_create
(
IUnknown
*
outer
,
IUnknown
**
out
);
HRESULT
mpeg_layer3_decoder_create
(
IUnknown
*
outer
,
IUnknown
**
out
);
HRESULT
mpeg_splitter_create
(
IUnknown
*
outer
,
IUnknown
**
out
);
HRESULT
wave_parser_create
(
IUnknown
*
outer
,
IUnknown
**
out
);
...
...
dlls/winegstreamer/main.c
View file @
481fd0ec
...
...
@@ -657,6 +657,7 @@ static const IClassFactoryVtbl class_factory_vtbl =
static
struct
class_factory
avi_splitter_cf
=
{{
&
class_factory_vtbl
},
avi_splitter_create
};
static
struct
class_factory
decodebin_parser_cf
=
{{
&
class_factory_vtbl
},
decodebin_parser_create
};
static
struct
class_factory
mpeg_audio_codec_cf
=
{{
&
class_factory_vtbl
},
mpeg_audio_codec_create
};
static
struct
class_factory
mpeg_video_codec_cf
=
{{
&
class_factory_vtbl
},
mpeg_video_codec_create
};
static
struct
class_factory
mpeg_layer3_decoder_cf
=
{{
&
class_factory_vtbl
},
mpeg_layer3_decoder_create
};
static
struct
class_factory
mpeg_splitter_cf
=
{{
&
class_factory_vtbl
},
mpeg_splitter_create
};
static
struct
class_factory
wave_parser_cf
=
{{
&
class_factory_vtbl
},
wave_parser_create
};
...
...
@@ -686,6 +687,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
factory
=
&
decodebin_parser_cf
;
else
if
(
IsEqualGUID
(
clsid
,
&
CLSID_CMpegAudioCodec
))
factory
=
&
mpeg_audio_codec_cf
;
else
if
(
IsEqualGUID
(
clsid
,
&
CLSID_CMpegVideoCodec
))
factory
=
&
mpeg_video_codec_cf
;
else
if
(
IsEqualGUID
(
clsid
,
&
CLSID_mpeg_layer3_decoder
))
factory
=
&
mpeg_layer3_decoder_cf
;
else
if
(
IsEqualGUID
(
clsid
,
&
CLSID_MPEG1Splitter
))
...
...
@@ -799,6 +802,38 @@ static const REGFILTER2 reg_mpeg_audio_codec =
.
u
.
s2
.
rgPins2
=
reg_mpeg_audio_codec_pins
,
};
static
const
REGPINTYPES
reg_mpeg_video_codec_sink_mts
[
2
]
=
{
{
&
MEDIATYPE_Video
,
&
MEDIASUBTYPE_MPEG1Packet
},
{
&
MEDIATYPE_Video
,
&
MEDIASUBTYPE_MPEG1Payload
},
};
static
const
REGPINTYPES
reg_mpeg_video_codec_source_mts
[
1
]
=
{
{
&
MEDIATYPE_Video
,
&
GUID_NULL
},
};
static
const
REGFILTERPINS2
reg_mpeg_video_codec_pins
[
2
]
=
{
{
.
nMediaTypes
=
2
,
.
lpMediaType
=
reg_mpeg_video_codec_sink_mts
,
},
{
.
dwFlags
=
REG_PINFLAG_B_OUTPUT
,
.
nMediaTypes
=
1
,
.
lpMediaType
=
reg_mpeg_video_codec_source_mts
,
},
};
static
const
REGFILTER2
reg_mpeg_video_codec
=
{
.
dwVersion
=
2
,
.
dwMerit
=
0x40000001
,
.
u
.
s2
.
cPins2
=
2
,
.
u
.
s2
.
rgPins2
=
reg_mpeg_video_codec_pins
,
};
static
const
REGPINTYPES
reg_mpeg_layer3_decoder_sink_mts
[
1
]
=
{
{
&
MEDIATYPE_Audio
,
&
MEDIASUBTYPE_MP3
},
...
...
@@ -1034,6 +1069,8 @@ HRESULT WINAPI DllRegisterServer(void)
L"GStreamer splitter filter"
,
NULL
,
NULL
,
NULL
,
&
reg_decodebin_parser
);
IFilterMapper2_RegisterFilter
(
mapper
,
&
CLSID_CMpegAudioCodec
,
L"MPEG Audio Decoder"
,
NULL
,
NULL
,
NULL
,
&
reg_mpeg_audio_codec
);
IFilterMapper2_RegisterFilter
(
mapper
,
&
CLSID_CMpegVideoCodec
,
L"MPEG Video Decoder"
,
NULL
,
NULL
,
NULL
,
&
reg_mpeg_video_codec
);
IFilterMapper2_RegisterFilter
(
mapper
,
&
CLSID_mpeg_layer3_decoder
,
L"MPEG Layer-3 Decoder"
,
NULL
,
NULL
,
NULL
,
&
reg_mpeg_layer3_decoder
);
IFilterMapper2_RegisterFilter
(
mapper
,
&
CLSID_MPEG1Splitter
,
...
...
@@ -1075,6 +1112,7 @@ HRESULT WINAPI DllUnregisterServer(void)
IFilterMapper2_UnregisterFilter
(
mapper
,
NULL
,
NULL
,
&
CLSID_AviSplitter
);
IFilterMapper2_UnregisterFilter
(
mapper
,
NULL
,
NULL
,
&
CLSID_decodebin_parser
);
IFilterMapper2_UnregisterFilter
(
mapper
,
NULL
,
NULL
,
&
CLSID_CMpegAudioCodec
);
IFilterMapper2_UnregisterFilter
(
mapper
,
NULL
,
NULL
,
&
CLSID_CMpegVideoCodec
);
IFilterMapper2_UnregisterFilter
(
mapper
,
NULL
,
NULL
,
&
CLSID_mpeg_layer3_decoder
);
IFilterMapper2_UnregisterFilter
(
mapper
,
NULL
,
NULL
,
&
CLSID_MPEG1Splitter
);
IFilterMapper2_UnregisterFilter
(
mapper
,
NULL
,
NULL
,
&
CLSID_WAVEParser
);
...
...
dlls/winegstreamer/quartz_parser.c
View file @
481fd0ec
...
...
@@ -1933,6 +1933,12 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface,
VIDEOINFOHEADER
*
format
=
(
VIDEOINFOHEADER
*
)
pin
->
pin
.
pin
.
mt
.
pbFormat
;
buffer_size
=
format
->
bmiHeader
.
biSizeImage
;
}
else
if
(
IsEqualGUID
(
&
pin
->
pin
.
pin
.
mt
.
formattype
,
&
FORMAT_MPEGVideo
))
{
MPEG1VIDEOINFO
*
format
=
(
MPEG1VIDEOINFO
*
)
pin
->
pin
.
pin
.
mt
.
pbFormat
;
buffer_size
=
format
->
hdr
.
bmiHeader
.
biSizeImage
;
buffer_count
=
8
;
}
else
if
(
IsEqualGUID
(
&
pin
->
pin
.
pin
.
mt
.
formattype
,
&
FORMAT_WaveFormatEx
)
&&
(
IsEqualGUID
(
&
pin
->
pin
.
pin
.
mt
.
subtype
,
&
MEDIASUBTYPE_PCM
)
||
IsEqualGUID
(
&
pin
->
pin
.
pin
.
mt
.
subtype
,
&
MEDIASUBTYPE_IEEE_FLOAT
)))
...
...
dlls/winegstreamer/quartz_transform.c
View file @
481fd0ec
...
...
@@ -738,6 +738,147 @@ HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out)
return
hr
;
}
static
HRESULT
mpeg_video_codec_sink_query_accept
(
struct
transform
*
filter
,
const
AM_MEDIA_TYPE
*
mt
)
{
if
(
!
IsEqualGUID
(
&
mt
->
majortype
,
&
MEDIATYPE_Video
)
||
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_MPEG1Payload
)
||
!
IsEqualGUID
(
&
mt
->
formattype
,
&
FORMAT_MPEGVideo
)
||
mt
->
cbFormat
<
sizeof
(
MPEG1VIDEOINFO
))
return
S_FALSE
;
return
S_OK
;
}
static
HRESULT
mpeg_video_codec_source_query_accept
(
struct
transform
*
filter
,
const
AM_MEDIA_TYPE
*
mt
)
{
if
(
!
filter
->
sink
.
pin
.
peer
)
return
S_FALSE
;
if
(
!
IsEqualGUID
(
&
mt
->
majortype
,
&
MEDIATYPE_Video
)
||
!
IsEqualGUID
(
&
mt
->
formattype
,
&
FORMAT_VideoInfo
)
||
mt
->
cbFormat
<
sizeof
(
VIDEOINFOHEADER
))
return
S_FALSE
;
if
(
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_YV12
)
/* missing: MEDIASUBTYPE_Y41P, not supported by GStreamer */
&&
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_YUY2
)
&&
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_UYVY
)
&&
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_RGB24
)
&&
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_RGB32
)
&&
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_RGB565
)
&&
!
IsEqualGUID
(
&
mt
->
subtype
,
&
MEDIASUBTYPE_RGB555
)
/* missing: MEDIASUBTYPE_RGB8, not supported by GStreamer */
)
return
S_FALSE
;
return
S_OK
;
}
static
HRESULT
mpeg_video_codec_source_get_media_type
(
struct
transform
*
filter
,
unsigned
int
index
,
AM_MEDIA_TYPE
*
mt
)
{
static
const
enum
wg_video_format
formats
[]
=
{
WG_VIDEO_FORMAT_YV12
,
WG_VIDEO_FORMAT_YUY2
,
WG_VIDEO_FORMAT_UYVY
,
WG_VIDEO_FORMAT_BGR
,
WG_VIDEO_FORMAT_BGRx
,
WG_VIDEO_FORMAT_RGB16
,
WG_VIDEO_FORMAT_RGB15
,
};
const
MPEG1VIDEOINFO
*
input_format
=
(
MPEG1VIDEOINFO
*
)
filter
->
sink
.
pin
.
mt
.
pbFormat
;
struct
wg_format
wg_format
=
{};
VIDEOINFO
*
video_format
;
if
(
!
filter
->
sink
.
pin
.
peer
)
return
VFW_S_NO_MORE_ITEMS
;
if
(
index
>=
ARRAY_SIZE
(
formats
))
return
VFW_S_NO_MORE_ITEMS
;
input_format
=
(
MPEG1VIDEOINFO
*
)
filter
->
sink
.
pin
.
mt
.
pbFormat
;
wg_format
.
major_type
=
WG_MAJOR_TYPE_VIDEO
;
wg_format
.
u
.
video
.
format
=
formats
[
index
];
wg_format
.
u
.
video
.
width
=
input_format
->
hdr
.
bmiHeader
.
biWidth
;
wg_format
.
u
.
video
.
height
=
input_format
->
hdr
.
bmiHeader
.
biHeight
;
wg_format
.
u
.
video
.
fps_n
=
10000000
;
wg_format
.
u
.
video
.
fps_d
=
input_format
->
hdr
.
AvgTimePerFrame
;
if
(
!
amt_from_wg_format
(
mt
,
&
wg_format
,
false
))
return
E_OUTOFMEMORY
;
video_format
=
(
VIDEOINFO
*
)
mt
->
pbFormat
;
video_format
->
bmiHeader
.
biHeight
=
abs
(
video_format
->
bmiHeader
.
biHeight
);
SetRect
(
&
video_format
->
rcSource
,
0
,
0
,
video_format
->
bmiHeader
.
biWidth
,
video_format
->
bmiHeader
.
biHeight
);
video_format
->
bmiHeader
.
biXPelsPerMeter
=
2000
;
video_format
->
bmiHeader
.
biYPelsPerMeter
=
2000
;
video_format
->
dwBitRate
=
MulDiv
(
video_format
->
bmiHeader
.
biSizeImage
*
8
,
10000000
,
video_format
->
AvgTimePerFrame
);
mt
->
lSampleSize
=
video_format
->
bmiHeader
.
biSizeImage
;
mt
->
bTemporalCompression
=
FALSE
;
mt
->
bFixedSizeSamples
=
TRUE
;
return
S_OK
;
}
static
HRESULT
mpeg_video_codec_source_decide_buffer_size
(
struct
transform
*
filter
,
IMemAllocator
*
allocator
,
ALLOCATOR_PROPERTIES
*
props
)
{
VIDEOINFOHEADER
*
output_format
=
(
VIDEOINFOHEADER
*
)
filter
->
source
.
pin
.
mt
.
pbFormat
;
ALLOCATOR_PROPERTIES
ret_props
;
props
->
cBuffers
=
max
(
props
->
cBuffers
,
1
);
props
->
cbBuffer
=
max
(
props
->
cbBuffer
,
output_format
->
bmiHeader
.
biSizeImage
);
props
->
cbAlign
=
max
(
props
->
cbAlign
,
1
);
return
IMemAllocator_SetProperties
(
allocator
,
props
,
&
ret_props
);
}
static
const
struct
transform_ops
mpeg_video_codec_transform_ops
=
{
mpeg_video_codec_sink_query_accept
,
mpeg_video_codec_source_query_accept
,
mpeg_video_codec_source_get_media_type
,
mpeg_video_codec_source_decide_buffer_size
,
};
HRESULT
mpeg_video_codec_create
(
IUnknown
*
outer
,
IUnknown
**
out
)
{
static
const
struct
wg_format
output_format
=
{
.
major_type
=
WG_MAJOR_TYPE_VIDEO
,
.
u
.
video
=
{
.
format
=
WG_VIDEO_FORMAT_I420
,
/* size doesn't matter, this one is only used to check if the GStreamer plugin exists */
},
};
static
const
struct
wg_format
input_format
=
{
.
major_type
=
WG_MAJOR_TYPE_VIDEO_MPEG1
,
.
u
.
video_mpeg1
=
{},
};
struct
wg_transform_attrs
attrs
=
{
0
};
wg_transform_t
transform
;
struct
transform
*
object
;
HRESULT
hr
;
transform
=
wg_transform_create
(
&
input_format
,
&
output_format
,
&
attrs
);
if
(
!
transform
)
{
ERR_
(
winediag
)(
"GStreamer doesn't support MPEG-1 video decoding, please install appropriate plugins.
\n
"
);
return
E_FAIL
;
}
wg_transform_destroy
(
transform
);
hr
=
transform_create
(
outer
,
&
CLSID_CMpegVideoCodec
,
&
mpeg_video_codec_transform_ops
,
&
object
);
if
(
FAILED
(
hr
))
return
hr
;
wcscpy
(
object
->
sink
.
pin
.
name
,
L"Input"
);
wcscpy
(
object
->
source
.
pin
.
name
,
L"Output"
);
TRACE
(
"Created MPEG video decoder %p.
\n
"
,
object
);
*
out
=
&
object
->
filter
.
IUnknown_inner
;
return
hr
;
}
static
HRESULT
mpeg_layer3_decoder_sink_query_accept
(
struct
transform
*
filter
,
const
AM_MEDIA_TYPE
*
mt
)
{
const
MPEGLAYER3WAVEFORMAT
*
format
;
...
...
dlls/winegstreamer/wg_transform.c
View file @
481fd0ec
...
...
@@ -358,6 +358,7 @@ NTSTATUS wg_transform_create(void *args)
case
WG_MAJOR_TYPE_VIDEO_CINEPAK
:
case
WG_MAJOR_TYPE_VIDEO_INDEO
:
case
WG_MAJOR_TYPE_VIDEO_WMV
:
case
WG_MAJOR_TYPE_VIDEO_MPEG1
:
if
(
!
(
element
=
find_element
(
GST_ELEMENT_FACTORY_TYPE_DECODER
,
src_caps
,
raw_caps
))
||
!
append_element
(
transform
->
container
,
element
,
&
first
,
&
last
))
{
...
...
@@ -369,7 +370,6 @@ NTSTATUS wg_transform_create(void *args)
case
WG_MAJOR_TYPE_AUDIO
:
case
WG_MAJOR_TYPE_VIDEO
:
break
;
case
WG_MAJOR_TYPE_VIDEO_MPEG1
:
case
WG_MAJOR_TYPE_UNKNOWN
:
GST_FIXME
(
"Format %u not implemented!"
,
input_format
.
major_type
);
gst_caps_unref
(
raw_caps
);
...
...
dlls/winegstreamer/winegstreamer_classes.idl
View file @
481fd0ec
...
...
@@ -36,6 +36,13 @@ coclass AviSplitter {}
coclass
CMpegAudioCodec
{}
[
helpstring
(
"MPEG Video Decoder"
),
threading
(
both
),
uuid
(
feb50740
-
7b
ef
-
11
ce
-
9b
d9
-
0000
e202599c
)
]
coclass
CMpegVideoCodec
{}
[
helpstring
(
"MPEG Layer-3 Decoder"
),
threading
(
both
),
uuid
(
38b
e3000
-
dbf4
-
11
d0
-860e-00
a024cfef6d
)
...
...
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