Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
bb7f54bb
Commit
bb7f54bb
authored
Aug 17, 2004
by
Gildas Bazin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/codec/dmo/*: added dmo encoder (can't get video encoding to work though).
parent
2dfaaa53
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1736 additions
and
1072 deletions
+1736
-1072
modules/codec/dmo/dmo.c
modules/codec/dmo/dmo.c
+1468
-811
modules/codec/dmo/dmo.h
modules/codec/dmo/dmo.h
+268
-261
No files found.
modules/codec/dmo/dmo.c
View file @
bb7f54bb
...
...
@@ -21,6 +21,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define DMO_DEBUG 1
/*****************************************************************************
* Preamble
*****************************************************************************/
...
...
@@ -78,18 +79,32 @@ static int pi_channels_maps[7] =
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
int
DecoderOpen
(
vlc_object_t
*
);
static
int
DecOpen
(
vlc_object_t
*
);
static
void
DecoderClose
(
vlc_object_t
*
);
static
void
*
DecodeBlock
(
decoder_t
*
,
block_t
**
);
static
int
EncoderOpen
(
vlc_object_t
*
);
static
int
EncOpen
(
vlc_object_t
*
);
static
void
EncoderClose
(
vlc_object_t
*
);
static
block_t
*
EncodeBlock
(
encoder_t
*
,
void
*
);
static
int
LoadDMO
(
vlc_object_t
*
,
HINSTANCE
*
,
IMediaObject
**
,
es_format_t
*
,
vlc_bool_t
);
static
void
CopyPicture
(
decoder_t
*
,
picture_t
*
,
uint8_t
*
);
vlc_module_begin
();
set_description
(
_
(
"DirectMedia Object decoder"
)
);
add_shortcut
(
"dmo"
);
set_capability
(
"decoder"
,
1
);
set_callbacks
(
Open
,
DecoderClose
);
set_callbacks
(
DecoderOpen
,
DecoderClose
);
# define ENC_CFG_PREFIX "sout-dmo-"
add_submodule
();
set_description
(
_
(
"DirectMedia Object encoder"
)
);
set_capability
(
"encoder"
,
10
);
set_callbacks
(
EncoderOpen
,
EncoderClose
);
vlc_module_end
();
/*****************************************************************************
...
...
@@ -107,7 +122,7 @@ struct decoder_sys_t
int
i_min_output
;
uint8_t
*
p_buffer
;
audio_date_t
end_date
;
date_t
end_date
;
#ifdef LOADER
ldt_fs_t
*
ldt_fs
;
...
...
@@ -121,12 +136,18 @@ static const GUID guid_wma9 = { 0x27ca0808, 0x01f5, 0x4e7a, { 0x8b, 0x05, 0x87,
static
const
GUID
guid_wmv
=
{
0x82d353df
,
0x90bd
,
0x4382
,
{
0x8b
,
0xc2
,
0x3f
,
0x61
,
0x92
,
0xb7
,
0x6e
,
0x34
}
};
static
const
GUID
guid_wma
=
{
0x874131cb
,
0x4ecc
,
0x443b
,
{
0x89
,
0x48
,
0x74
,
0x6b
,
0x89
,
0x59
,
0x5d
,
0x20
}
};
static
const
struct
static
const
GUID
guid_wmv_enc
=
{
0x3181343b
,
0x94a2
,
0x4feb
,
{
0xad
,
0xef
,
0x30
,
0xa1
,
0xdd
,
0xe6
,
0x17
,
0xb4
}
};
static
const
GUID
guid_wma_enc
=
{
0x70f598e9
,
0xf4ab
,
0x495a
,
{
0x99
,
0xe2
,
0xa7
,
0xc4
,
0xd3
,
0xd8
,
0x9a
,
0xbf
}
};
typedef
struct
{
vlc_fourcc_t
i_fourcc
;
const
char
*
psz_dll
;
const
GUID
*
p_guid
;
}
codecs_table
[]
=
}
codec_dll
;
static
const
codec_dll
decoders_table
[]
=
{
/* WM3 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'3'
),
"wmv9dmod.dll"
,
&
guid_wmv9
},
...
...
@@ -138,215 +159,129 @@ static const struct
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'1'
),
"wmvdmod.dll"
,
&
guid_wmv
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'1'
),
"wmvdmod.dll"
,
&
guid_wmv
},
/* WMA 3
*/
/* WMA 3
*/
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'3'
),
"wma9dmod.dll"
,
&
guid_wma9
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'a'
,
'3'
),
"wma9dmod.dll"
,
&
guid_wma9
},
/* WMA 2 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'2'
),
"wma9dmod.dll"
,
&
guid_wma9
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'a'
,
'2'
),
"wma9dmod.dll"
,
&
guid_wma9
},
/* */
{
0
,
NULL
,
NULL
}
};
static
const
codec_dll
encoders_table
[]
=
{
/* WMV2 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'2'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'1'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
/* WMV1 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'1'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'1'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
/* WMA 3 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'3'
),
"wmadmoe.dll"
,
&
guid_wma_enc
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'a'
,
'3'
),
"wmadmoe.dll"
,
&
guid_wma_enc
},
/* WMA 2 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'2'
),
"wmadmoe.dll"
,
&
guid_wma_enc
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'a'
,
'2'
),
"wmadmoe.dll"
,
&
guid_wma_enc
},
/* */
{
0
,
NULL
,
NULL
}
};
#endif
/* LOADER */
static
void
WINAPI
DMOFreeMediaType
(
DMO_MEDIA_TYPE
*
mt
)
{
if
(
mt
->
cbFormat
!=
0
)
CoTaskMemFree
(
(
PVOID
)
mt
->
pbFormat
);
if
(
mt
->
pUnk
!=
NULL
)
mt
->
pUnk
->
vt
->
Release
(
(
IUnknown
*
)
mt
->
pUnk
);
mt
->
cbFormat
=
0
;
mt
->
pbFormat
=
NULL
;
mt
->
pUnk
=
NULL
;
}
/*****************************************************************************
*
Open: open dmo codec
*
DecoderOpen: open dmo codec
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
static
int
DecoderOpen
(
vlc_object_t
*
p_this
)
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
#ifndef LOADER
return
DecoderOpen
(
p_this
);
int
i_ret
=
DecOpen
(
p_this
);
if
(
i_ret
!=
VLC_SUCCESS
)
return
i_ret
;
#else
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
int
i
;
/* We can't open it now, because of ldt_keeper or something
* Open/Decode/Close has to be done in the same thread */
int
i
;
p_dec
->
p_sys
=
NULL
;
/* Probe if we support it */
for
(
i
=
0
;
codecs_table
[
i
].
i_fourcc
!=
0
;
i
++
)
for
(
i
=
0
;
decoders_table
[
i
].
i_fourcc
!=
0
;
i
++
)
{
if
(
codecs_table
[
i
].
i_fourcc
==
p_dec
->
fmt_in
.
i_codec
)
if
(
decoders_table
[
i
].
i_fourcc
==
p_dec
->
fmt_in
.
i_codec
)
{
msg_Dbg
(
p_dec
,
"DMO codec for %4.4s may work with dll=%s"
,
(
char
*
)
&
p_dec
->
fmt_in
.
i_codec
,
codecs_table
[
i
].
psz_dll
);
/* Set callbacks */
p_dec
->
pf_decode_video
=
(
picture_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
p_dec
->
pf_decode_audio
=
(
aout_buffer_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
return
VLC_SUCCESS
;
(
char
*
)
&
p_dec
->
fmt_in
.
i_codec
,
decoders_table
[
i
].
psz_dll
);
break
;
}
}
return
VLC_EGENERIC
;
p_dec
->
p_sys
=
NULL
;
if
(
!
decoders_table
[
i
].
i_fourcc
)
return
VLC_EGENERIC
;
#endif
/* LOADER */
/* Set callbacks */
p_dec
->
pf_decode_video
=
(
picture_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
p_dec
->
pf_decode_audio
=
(
aout_buffer_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Dec
oderOpen: open dmo codec
* Dec
Open: open dmo codec
*****************************************************************************/
static
int
Dec
oderOpen
(
vlc_object_t
*
p_this
)
static
int
Dec
Open
(
vlc_object_t
*
p_this
)
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
NULL
;
DMO_PARTIAL_MEDIATYPE
dmo_partial_type
;
DMO_MEDIA_TYPE
dmo_input_type
,
dmo_output_type
;
IMediaObject
*
p_dmo
=
NULL
;
HINSTANCE
hmsdmo_dll
=
NULL
;
VIDEOINFOHEADER
*
p_vih
=
NULL
;
WAVEFORMATEX
*
p_wf
=
NULL
;
#ifdef LOADER
ldt_fs_t
*
ldt_fs
=
Setup_LDT_Keeper
();
#endif
/* LOADER */
HINSTANCE
hmsdmo_dll
=
NULL
;
/* Look for a DMO which can handle the requested codec */
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
{
uint16_t
i_tag
;
dmo_partial_type
.
type
=
MEDIATYPE_Audio
;
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
dmo_partial_type
.
subtype
.
Data1
=
p_dec
->
fmt_in
.
i_codec
;
fourcc_to_wf_tag
(
p_dec
->
fmt_in
.
i_codec
,
&
i_tag
);
if
(
i_tag
)
dmo_partial_type
.
subtype
.
Data1
=
i_tag
;
}
else
{
dmo_partial_type
.
type
=
MEDIATYPE_Video
;
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
dmo_partial_type
.
subtype
.
Data1
=
p_dec
->
fmt_in
.
i_codec
;
}
#ifndef LOADER
{
IEnumDMO
*
p_enum_dmo
=
NULL
;
WCHAR
*
psz_dmo_name
;
GUID
clsid_dmo
;
long
(
STDCALL
*
OurDMOEnum
)(
const
GUID
*
,
uint32_t
,
uint32_t
,
const
DMO_PARTIAL_MEDIATYPE
*
,
uint32_t
,
const
DMO_PARTIAL_MEDIATYPE
*
,
IEnumDMO
**
);
/* Load msdmo DLL */
hmsdmo_dll
=
LoadLibrary
(
"msdmo.dll"
);
if
(
hmsdmo_dll
==
NULL
)
{
msg_Dbg
(
p_dec
,
"failed loading msdmo.dll"
);
return
VLC_EGENERIC
;
}
OurDMOEnum
=
(
void
*
)
GetProcAddress
(
hmsdmo_dll
,
"DMOEnum"
);
if
(
OurDMOEnum
==
NULL
)
{
msg_Dbg
(
p_dec
,
"GetProcAddress failed to find DMOEnum()"
);
FreeLibrary
(
hmsdmo_dll
);
return
VLC_EGENERIC
;
}
#else
/* Initialize OLE/COM */
CoInitialize
(
0
);
#endif
/* LOADER */
if
(
OurDMOEnum
(
&
GUID_NULL
,
1
/*DMO_ENUMF_INCLUDE_KEYED*/
,
1
,
&
dmo_partial_type
,
0
,
NULL
,
&
p_enum_dmo
)
)
{
goto
error
;
}
/* Pickup the first available codec */
if
(
p_enum_dmo
->
vt
->
Next
(
p_enum_dmo
,
1
,
&
clsid_dmo
,
&
psz_dmo_name
,
NULL
)
)
{
goto
error
;
}
p_enum_dmo
->
vt
->
Release
(
(
IUnknown
*
)
p_enum_dmo
);
#if 1
{
char
psz_temp
[
MAX_PATH
];
wcstombs
(
psz_temp
,
psz_dmo_name
,
MAX_PATH
);
msg_Dbg
(
p_dec
,
"found DMO: %s"
,
psz_temp
);
}
#endif
CoTaskMemFree
(
psz_dmo_name
);
/* Create DMO */
if
(
CoCreateInstance
(
&
clsid_dmo
,
NULL
,
CLSCTX_INPROC
,
&
IID_IMediaObject
,
(
void
**
)
&
p_dmo
)
)
if
(
LoadDMO
(
p_this
,
&
hmsdmo_dll
,
&
p_dmo
,
&
p_dec
->
fmt_in
,
VLC_FALSE
)
!=
VLC_SUCCESS
)
{
msg_Err
(
p_dec
,
"can't create DMO"
);
hmsdmo_dll
=
0
;
p_dmo
=
0
;
goto
error
;
}
}
#else
/* LOADER */
{
GETCLASS
GetClass
;
IClassFactory
*
cFactory
=
NULL
;
IUnknown
*
cObject
=
NULL
;
int
i_err
;
int
i_codec
;
for
(
i_codec
=
0
;
codecs_table
[
i_codec
].
i_fourcc
!=
0
;
i_codec
++
)
{
if
(
codecs_table
[
i_codec
].
i_fourcc
==
p_dec
->
fmt_in
.
i_codec
)
break
;
}
if
(
codecs_table
[
i_codec
].
i_fourcc
==
0
)
return
VLC_EGENERIC
;
/* Can't happen */
hmsdmo_dll
=
LoadLibrary
(
codecs_table
[
i_codec
].
psz_dll
);
if
(
hmsdmo_dll
==
NULL
)
{
msg_Dbg
(
p_dec
,
"failed loading '%s'"
,
codecs_table
[
i_codec
].
psz_dll
);
return
VLC_EGENERIC
;
}
GetClass
=
(
GETCLASS
)
GetProcAddress
(
hmsdmo_dll
,
"DllGetClassObject"
);
if
(
!
GetClass
)
{
msg_Dbg
(
p_dec
,
"GetProcAddress failed to find DllGetClassObject()"
);
FreeLibrary
(
hmsdmo_dll
);
return
VLC_EGENERIC
;
}
i_err
=
GetClass
(
codecs_table
[
i_codec
].
p_guid
,
&
IID_IClassFactory
,
(
void
**
)
&
cFactory
);
if
(
i_err
||
cFactory
==
NULL
)
{
msg_Dbg
(
p_dec
,
"no such class object"
);
FreeLibrary
(
hmsdmo_dll
);
return
VLC_EGENERIC
;
}
i_err
=
cFactory
->
vt
->
CreateInstance
(
cFactory
,
0
,
&
IID_IUnknown
,
(
void
**
)
&
cObject
);
cFactory
->
vt
->
Release
((
IUnknown
*
)
cFactory
);
if
(
i_err
||
!
cObject
)
{
msg_Dbg
(
p_dec
,
"class factory failure"
);
FreeLibrary
(
hmsdmo_dll
);
return
VLC_EGENERIC
;
}
i_err
=
cObject
->
vt
->
QueryInterface
(
cObject
,
&
IID_IMediaObject
,
(
void
**
)
&
p_dmo
);
cObject
->
vt
->
Release
((
IUnknown
*
)
cObject
);
}
#endif
/* LOADER */
/* Setup input format */
memset
(
&
dmo_input_type
,
0
,
sizeof
(
dmo_input_type
)
);
dmo_input_type
.
majortype
=
dmo_partial_type
.
type
;
dmo_input_type
.
subtype
=
dmo_partial_type
.
subtype
;
dmo_input_type
.
pUnk
=
0
;
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
{
uint16_t
i_tag
;
int
i_size
=
sizeof
(
WAVEFORMATEX
)
+
p_dec
->
fmt_in
.
i_extra
;
p_wf
=
malloc
(
i_size
);
...
...
@@ -354,7 +289,13 @@ static int DecoderOpen( vlc_object_t *p_this )
if
(
p_dec
->
fmt_in
.
i_extra
)
memcpy
(
&
p_wf
[
1
],
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
p_wf
->
wFormatTag
=
dmo_partial_type
.
subtype
.
Data1
;
dmo_input_type
.
majortype
=
MEDIATYPE_Audio
;
dmo_input_type
.
subtype
=
dmo_input_type
.
majortype
;
dmo_input_type
.
subtype
.
Data1
=
p_dec
->
fmt_in
.
i_codec
;
fourcc_to_wf_tag
(
p_dec
->
fmt_in
.
i_codec
,
&
i_tag
);
if
(
i_tag
)
dmo_input_type
.
subtype
.
Data1
=
i_tag
;
p_wf
->
wFormatTag
=
dmo_input_type
.
subtype
.
Data1
;
p_wf
->
nSamplesPerSec
=
p_dec
->
fmt_in
.
audio
.
i_rate
;
p_wf
->
nChannels
=
p_dec
->
fmt_in
.
audio
.
i_channels
;
p_wf
->
wBitsPerSample
=
p_dec
->
fmt_in
.
audio
.
i_bitspersample
;
...
...
@@ -365,7 +306,6 @@ static int DecoderOpen( vlc_object_t *p_this )
dmo_input_type
.
formattype
=
FORMAT_WaveFormatEx
;
dmo_input_type
.
cbFormat
=
i_size
;
dmo_input_type
.
pbFormat
=
(
char
*
)
p_wf
;
dmo_input_type
.
pUnk
=
NULL
;
dmo_input_type
.
bFixedSizeSamples
=
1
;
dmo_input_type
.
bTemporalCompression
=
0
;
dmo_input_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
...
...
@@ -382,7 +322,7 @@ static int DecoderOpen( vlc_object_t *p_this )
memcpy
(
&
p_vih
[
1
],
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
p_bih
=
&
p_vih
->
bmiHeader
;
p_bih
->
biCompression
=
dmo_partial_type
.
subtype
.
Data1
;
p_bih
->
biCompression
=
p_dec
->
fmt_in
.
i_codec
;
p_bih
->
biWidth
=
p_dec
->
fmt_in
.
video
.
i_width
;
p_bih
->
biHeight
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_bih
->
biBitCount
=
p_dec
->
fmt_in
.
video
.
i_bits_per_pixel
;
...
...
@@ -395,7 +335,10 @@ static int DecoderOpen( vlc_object_t *p_this )
p_vih
->
rcSource
.
bottom
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_vih
->
rcTarget
=
p_vih
->
rcSource
;
dmo_input_type
.
formattype
=
MEDIASUBTYPE_VideoInfo
;
dmo_input_type
.
majortype
=
MEDIATYPE_Video
;
dmo_input_type
.
subtype
=
dmo_input_type
.
majortype
;
dmo_input_type
.
subtype
.
Data1
=
p_dec
->
fmt_in
.
i_codec
;
dmo_input_type
.
formattype
=
FORMAT_VideoInfo
;
dmo_input_type
.
bFixedSizeSamples
=
0
;
dmo_input_type
.
bTemporalCompression
=
1
;
dmo_input_type
.
cbFormat
=
i_size
;
...
...
@@ -411,7 +354,6 @@ static int DecoderOpen( vlc_object_t *p_this )
/* Setup output format */
memset
(
&
dmo_output_type
,
0
,
sizeof
(
dmo_output_type
)
);
dmo_output_type
.
majortype
=
dmo_partial_type
.
type
;
dmo_output_type
.
pUnk
=
0
;
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
...
...
@@ -435,6 +377,7 @@ static int DecoderOpen( vlc_object_t *p_this )
p_wf
->
nSamplesPerSec
*
p_wf
->
nBlockAlign
;
p_wf
->
cbSize
=
0
;
dmo_output_type
.
majortype
=
MEDIATYPE_Audio
;
dmo_output_type
.
formattype
=
FORMAT_WaveFormatEx
;
dmo_output_type
.
subtype
=
MEDIASUBTYPE_PCM
;
dmo_output_type
.
cbFormat
=
sizeof
(
WAVEFORMATEX
);
...
...
@@ -442,7 +385,6 @@ static int DecoderOpen( vlc_object_t *p_this )
dmo_output_type
.
bFixedSizeSamples
=
1
;
dmo_output_type
.
bTemporalCompression
=
0
;
dmo_output_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
dmo_output_type
.
pUnk
=
NULL
;
}
else
{
...
...
@@ -455,11 +397,11 @@ static int DecoderOpen( vlc_object_t *p_this )
p_dec
->
fmt_out
.
video
.
i_aspect
=
VOUT_ASPECT_FACTOR
*
p_dec
->
fmt_out
.
video
.
i_width
/
p_dec
->
fmt_out
.
video
.
i_height
;
dmo_output_type
.
formattype
=
MEDIASUBTYPE_VideoInfo
;
dmo_output_type
.
formattype
=
FORMAT_VideoInfo
;
dmo_output_type
.
subtype
=
MEDIASUBTYPE_YV12
;
p_bih
=
&
p_vih
->
bmiHeader
;
p_bih
->
biCompression
=
dmo_partial_type
.
subtype
.
Data1
;
p_bih
->
biCompression
=
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
);
p_bih
->
biHeight
*=
-
1
;
p_bih
->
biBitCount
=
p_dec
->
fmt_out
.
video
.
i_bits_per_pixel
;
p_bih
->
biSizeImage
=
p_dec
->
fmt_in
.
video
.
i_width
*
...
...
@@ -469,6 +411,7 @@ static int DecoderOpen( vlc_object_t *p_this )
//p_bih->biPlanes = 1;
p_bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
dmo_output_type
.
majortype
=
MEDIATYPE_Video
;
dmo_output_type
.
bFixedSizeSamples
=
VLC_TRUE
;
dmo_output_type
.
bTemporalCompression
=
0
;
dmo_output_type
.
lSampleSize
=
p_bih
->
biSizeImage
;
...
...
@@ -476,6 +419,7 @@ static int DecoderOpen( vlc_object_t *p_this )
dmo_output_type
.
pbFormat
=
(
char
*
)
p_vih
;
}
#ifdef DMO_DEBUG
/* Enumerate output types */
if
(
p_dec
->
fmt_in
.
i_cat
==
VIDEO_ES
)
{
...
...
@@ -486,25 +430,10 @@ static int DecoderOpen( vlc_object_t *p_this )
{
msg_Dbg
(
p_dec
,
"available output chroma: %4.4s"
,
(
char
*
)
&
mt
.
subtype
.
Data1
);
DMOFreeMediaType
(
&
mt
);
}
}
/* Choose an output type.
* FIXME, get rid of the dmo_output_type code above. */
if
(
p_dec
->
fmt_in
.
i_cat
==
VIDEO_ES
)
{
int
i
=
0
;
DMO_MEDIA_TYPE
mt
;
while
(
!
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i
++
,
&
mt
)
)
{
if
(
dmo_output_type
.
subtype
.
Data1
==
mt
.
subtype
.
Data1
)
{
*
p_vih
=
*
(
VIDEOINFOHEADER
*
)
mt
.
pbFormat
;
break
;
}
}
}
#endif
if
(
p_dmo
->
vt
->
SetOutputType
(
p_dmo
,
0
,
&
dmo_output_type
,
0
)
)
{
...
...
@@ -550,16 +479,9 @@ static int DecoderOpen( vlc_object_t *p_this )
/* Set output properties */
p_dec
->
fmt_out
.
i_cat
=
p_dec
->
fmt_in
.
i_cat
;
if
(
p_dec
->
fmt_out
.
i_cat
==
AUDIO_ES
)
aout_DateInit
(
&
p_sys
->
end_date
,
p_dec
->
fmt_in
.
audio
.
i_rate
);
date_Init
(
&
p_sys
->
end_date
,
p_dec
->
fmt_in
.
audio
.
i_rate
,
1
);
else
aout_DateInit
(
&
p_sys
->
end_date
,
25
/* FIXME */
);
aout_DateSet
(
&
p_sys
->
end_date
,
0
);
/* Set callbacks */
p_dec
->
pf_decode_video
=
(
picture_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
p_dec
->
pf_decode_audio
=
(
aout_buffer_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
date_Init
(
&
p_sys
->
end_date
,
25
/* FIXME */
,
1
);
if
(
p_vih
)
free
(
p_vih
);
if
(
p_wf
)
free
(
p_wf
);
...
...
@@ -567,9 +489,16 @@ static int DecoderOpen( vlc_object_t *p_this )
return
VLC_SUCCESS
;
error:
if
(
p_dmo
)
p_dmo
->
vt
->
Release
(
(
IUnknown
*
)
p_dmo
);
if
(
hmsdmo_dll
)
FreeLibrary
(
hmsdmo_dll
);
#ifdef LOADER
Restore_LDT_Keeper
(
ldt_fs
);
#else
/* Uninitialize OLE/COM */
CoUninitialize
();
FreeLibrary
(
hmsdmo_dll
);
#endif
/* LOADER */
if
(
p_vih
)
free
(
p_vih
);
if
(
p_wf
)
free
(
p_wf
);
...
...
@@ -579,73 +508,239 @@ static int DecoderOpen( vlc_object_t *p_this )
}
/*****************************************************************************
*
DecoderClose: close codec
*
LoadDMO: Load the DMO object
*****************************************************************************/
void
DecoderClose
(
vlc_object_t
*
p_this
)
static
int
LoadDMO
(
vlc_object_t
*
p_this
,
HINSTANCE
*
p_hmsdmo_dll
,
IMediaObject
**
pp_dmo
,
es_format_t
*
p_fmt
,
vlc_bool_t
b_out
)
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
/* Uninitialize OLE/COM */
CoUninitialize
();
DMO_PARTIAL_MEDIATYPE
dmo_partial_type
;
int
i_err
;
FreeLibrary
(
p_sys
->
hmsdmo_dll
);
#ifndef LOADER
IEnumDMO
*
p_enum_dmo
=
NULL
;
WCHAR
*
psz_dmo_name
;
GUID
clsid_dmo
;
#else
#if 0
#ifdef LOADER
Restore_LDT_Keeper( p_sys->ldt_fs );
#endif
GETCLASS
GetClass
;
IClassFactory
*
cFactory
=
NULL
;
IUnknown
*
cObject
=
NULL
;
codec_dll
*
codecs_table
=
b_out
?
encoders_table
:
decoders_table
;
int
i_codec
;
#endif
if
(
p_sys
->
p_buffer
)
free
(
p_sys
->
p_buffer
);
free
(
p_sys
);
}
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
static
void
*
DecodeBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_block
;
int
i_result
;
DMO_OUTPUT_DATA_BUFFER
db
;
CMediaBuffer
*
p_out
;
block_t
block_out
;
uint32_t
i_status
,
i_buffer_out
;
uint8_t
*
p_buffer_out
;
if
(
p_sys
==
NULL
)
{
if
(
DecoderOpen
(
VLC_OBJECT
(
p_dec
)
)
)
/* Look for a DMO which can handle the requested codec */
if
(
p_fmt
->
i_cat
==
AUDIO_ES
)
{
msg_Err
(
p_dec
,
"DecoderOpen failed"
);
return
NULL
;
uint16_t
i_tag
;
dmo_partial_type
.
type
=
MEDIATYPE_Audio
;
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
dmo_partial_type
.
subtype
.
Data1
=
p_fmt
->
i_codec
;
fourcc_to_wf_tag
(
p_fmt
->
i_codec
,
&
i_tag
);
if
(
i_tag
)
dmo_partial_type
.
subtype
.
Data1
=
i_tag
;
}
p_sys
=
p_dec
->
p_sys
;
else
{
dmo_partial_type
.
type
=
MEDIATYPE_Video
;
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
dmo_partial_type
.
subtype
.
Data1
=
p_fmt
->
i_codec
;
}
if
(
!
pp_block
)
return
NULL
;
p_block
=
*
pp_block
;
/* Won't work with streams with B-frames, but do we have any ? */
if
(
p_block
&&
p_block
->
i_pts
<=
0
)
p_block
->
i_pts
=
p_block
->
i_dts
;
#ifndef LOADER
long
(
STDCALL
*
OurDMOEnum
)(
const
GUID
*
,
uint32_t
,
uint32_t
,
const
DMO_PARTIAL_MEDIATYPE
*
,
uint32_t
,
const
DMO_PARTIAL_MEDIATYPE
*
,
IEnumDMO
**
);
/* Date management */
if
(
p_block
&&
p_block
->
i_pts
>
0
&&
p_block
->
i_pts
!=
aout_DateGet
(
&
p_sys
->
end_date
)
)
/* Load msdmo DLL */
*
p_hmsdmo_dll
=
LoadLibrary
(
"msdmo.dll"
);
if
(
*
p_hmsdmo_dll
==
NULL
)
{
msg_Dbg
(
p_this
,
"failed loading msdmo.dll"
);
return
VLC_EGENERIC
;
}
OurDMOEnum
=
(
void
*
)
GetProcAddress
(
*
p_hmsdmo_dll
,
"DMOEnum"
);
if
(
OurDMOEnum
==
NULL
)
{
aout_DateSet
(
&
p_sys
->
end_date
,
p_block
->
i_pts
);
msg_Dbg
(
p_this
,
"GetProcAddress failed to find DMOEnum()"
);
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
#if 0 /* Breaks the video decoding */
if( !aout_DateGet( &p_sys->end_date ) )
if
(
!
b_out
)
{
/* We've just started the stream, wait for the first PTS. */
i_err
=
OurDMOEnum
(
&
GUID_NULL
,
1
/*DMO_ENUMF_INCLUDE_KEYED*/
,
1
,
&
dmo_partial_type
,
0
,
NULL
,
&
p_enum_dmo
);
}
else
{
i_err
=
OurDMOEnum
(
&
GUID_NULL
,
1
/*DMO_ENUMF_INCLUDE_KEYED*/
,
0
,
NULL
,
1
,
&
dmo_partial_type
,
&
p_enum_dmo
);
}
if
(
i_err
)
{
CoUninitialize
();
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
/* Pickup the first available codec */
if
(
p_enum_dmo
->
vt
->
Next
(
p_enum_dmo
,
1
,
&
clsid_dmo
,
&
psz_dmo_name
,
NULL
)
)
{
CoUninitialize
();
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
p_enum_dmo
->
vt
->
Release
(
(
IUnknown
*
)
p_enum_dmo
);
#if 1
{
char
psz_temp
[
MAX_PATH
];
wcstombs
(
psz_temp
,
psz_dmo_name
,
MAX_PATH
);
msg_Dbg
(
p_this
,
"found DMO: %s"
,
psz_temp
);
}
#endif
CoTaskMemFree
(
psz_dmo_name
);
/* Create DMO */
if
(
CoCreateInstance
(
&
clsid_dmo
,
NULL
,
CLSCTX_INPROC
,
&
IID_IMediaObject
,
(
void
**
)
pp_dmo
)
)
{
msg_Err
(
p_this
,
"can't create DMO"
);
CoUninitialize
();
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
#else
/* LOADER */
for
(
i_codec
=
0
;
codecs_table
[
i_codec
].
i_fourcc
!=
0
;
i_codec
++
)
{
if
(
codecs_table
[
i_codec
].
i_fourcc
==
p_fmt
->
i_codec
)
break
;
}
if
(
codecs_table
[
i_codec
].
i_fourcc
==
0
)
return
VLC_EGENERIC
;
/* Can't happen */
*
p_hmsdmo_dll
=
LoadLibrary
(
codecs_table
[
i_codec
].
psz_dll
);
if
(
*
p_hmsdmo_dll
==
NULL
)
{
msg_Dbg
(
p_this
,
"failed loading '%s'"
,
codecs_table
[
i_codec
].
psz_dll
);
return
VLC_EGENERIC
;
}
GetClass
=
(
GETCLASS
)
GetProcAddress
(
*
p_hmsdmo_dll
,
"DllGetClassObject"
);
if
(
!
GetClass
)
{
msg_Dbg
(
p_this
,
"GetProcAddress failed to find DllGetClassObject()"
);
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
i_err
=
GetClass
(
codecs_table
[
i_codec
].
p_guid
,
&
IID_IClassFactory
,
(
void
**
)
&
cFactory
);
if
(
i_err
||
cFactory
==
NULL
)
{
msg_Dbg
(
p_this
,
"no such class object"
);
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
i_err
=
cFactory
->
vt
->
CreateInstance
(
cFactory
,
0
,
&
IID_IUnknown
,
(
void
**
)
&
cObject
);
cFactory
->
vt
->
Release
(
(
IUnknown
*
)
cFactory
);
if
(
i_err
||
!
cObject
)
{
msg_Dbg
(
p_this
,
"class factory failure"
);
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
i_err
=
cObject
->
vt
->
QueryInterface
(
cObject
,
&
IID_IMediaObject
,
(
void
**
)
pp_dmo
);
cObject
->
vt
->
Release
(
(
IUnknown
*
)
cObject
);
if
(
i_err
||
!*
pp_dmo
)
{
msg_Dbg
(
p_this
,
"QueryInterface failure"
);
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
}
#endif
/* LOADER */
return
VLC_SUCCESS
;
}
/*****************************************************************************
* DecoderClose: close codec
*****************************************************************************/
void
DecoderClose
(
vlc_object_t
*
p_this
)
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
if
(
!
p_sys
)
return
;
FreeLibrary
(
p_sys
->
hmsdmo_dll
);
#ifdef LOADER
#if 0
Restore_LDT_Keeper( p_sys->ldt_fs );
#endif
#else
/* Uninitialize OLE/COM */
CoUninitialize
();
#endif
if
(
p_sys
->
p_buffer
)
free
(
p_sys
->
p_buffer
);
free
(
p_sys
);
}
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
static
void
*
DecodeBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_block
;
int
i_result
;
DMO_OUTPUT_DATA_BUFFER
db
;
CMediaBuffer
*
p_out
;
block_t
block_out
;
uint32_t
i_status
;
if
(
p_sys
==
NULL
)
{
if
(
DecOpen
(
VLC_OBJECT
(
p_dec
)
)
)
{
msg_Err
(
p_dec
,
"DecOpen failed"
);
return
NULL
;
}
p_sys
=
p_dec
->
p_sys
;
}
if
(
!
pp_block
)
return
NULL
;
p_block
=
*
pp_block
;
/* Won't work with streams with B-frames, but do we have any ? */
if
(
p_block
&&
p_block
->
i_pts
<=
0
)
p_block
->
i_pts
=
p_block
->
i_dts
;
/* Date management */
if
(
p_block
&&
p_block
->
i_pts
>
0
&&
p_block
->
i_pts
!=
date_Get
(
&
p_sys
->
end_date
)
)
{
date_Set
(
&
p_sys
->
end_date
,
p_block
->
i_pts
);
}
#if 0 /* Breaks the video decoding */
if( !date_Get( &p_sys->end_date ) )
{
/* We've just started the stream, wait for the first PTS. */
if( p_block ) block_Release( p_block );
return NULL;
}
...
...
@@ -695,13 +790,11 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
/* Get output from the DMO */
block_out
.
p_buffer
=
p_sys
->
p_buffer
;
;
block_out
.
p_buffer
=
p_sys
->
p_buffer
;
block_out
.
i_buffer
=
0
;
p_out
=
CMediaBufferCreate
(
&
block_out
,
p_sys
->
i_min_output
,
VLC_FALSE
);
db
.
rtTimestamp
=
0
;
db
.
rtTimelength
=
0
;
db
.
dwStatus
=
0
;
memset
(
&
db
,
0
,
sizeof
(
db
)
);
db
.
pBuffer
=
(
IMediaBuffer
*
)
p_out
;
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessOutput
(
p_sys
->
p_dmo
,
...
...
@@ -725,16 +818,7 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
msg_Dbg
(
p_dec
,
"ProcessOutput(): success"
);
#endif
i_result
=
p_out
->
vt
->
GetBufferAndLength
(
(
IMediaBuffer
*
)
p_out
,
&
p_buffer_out
,
&
i_buffer_out
);
if
(
i_result
!=
S_OK
)
{
msg_Dbg
(
p_dec
,
"GetBufferAndLength(): failed"
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
return
NULL
;
}
if
(
!
i_buffer_out
)
if
(
!
block_out
.
i_buffer
)
{
#if DMO_DEBUG
msg_Dbg
(
p_dec
,
"ProcessOutput(): no output (i_buffer_out == 0)"
);
...
...
@@ -752,8 +836,8 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
CopyPicture
(
p_dec
,
p_pic
,
block_out
.
p_buffer
);
/* Date management */
p_pic
->
date
=
aout_DateGet
(
&
p_sys
->
end_date
);
aout_DateIncrement
(
&
p_sys
->
end_date
,
1
);
p_pic
->
date
=
date_Get
(
&
p_sys
->
end_date
);
date_Increment
(
&
p_sys
->
end_date
,
1
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
...
...
@@ -762,17 +846,18 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
else
{
aout_buffer_t
*
p_aout_buffer
;
int
i_samples
=
i_buffer_out
/
int
i_samples
=
block_out
.
i_buffer
/
(
p_dec
->
fmt_out
.
audio
.
i_bitspersample
*
p_dec
->
fmt_out
.
audio
.
i_channels
/
8
);
p_aout_buffer
=
p_dec
->
pf_aout_buffer_new
(
p_dec
,
i_samples
);
memcpy
(
p_aout_buffer
->
p_buffer
,
p_buffer_out
,
i_buffer_out
);
memcpy
(
p_aout_buffer
->
p_buffer
,
block_out
.
p_buffer
,
block_out
.
i_buffer
);
/* Date management */
p_aout_buffer
->
start_date
=
aout_DateGet
(
&
p_sys
->
end_date
);
p_aout_buffer
->
start_date
=
date_Get
(
&
p_sys
->
end_date
);
p_aout_buffer
->
end_date
=
aout_DateIncrement
(
&
p_sys
->
end_date
,
i_samples
);
date_Increment
(
&
p_sys
->
end_date
,
i_samples
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
...
...
@@ -809,3 +894,575 @@ static void CopyPicture( decoder_t *p_dec, picture_t *p_pic, uint8_t *p_in )
p_pic
->
p
[
1
].
p_pixels
=
p_pic
->
p
[
2
].
p_pixels
;
p_pic
->
p
[
2
].
p_pixels
=
p_dst
;
}
/****************************************************************************
* Encoder descriptor declaration
****************************************************************************/
struct
encoder_sys_t
{
HINSTANCE
hmsdmo_dll
;
IMediaObject
*
p_dmo
;
int
i_min_output
;
date_t
end_date
;
#ifdef LOADER
ldt_fs_t
*
ldt_fs
;
#endif
};
/*****************************************************************************
* EncoderOpen: open dmo codec
*****************************************************************************/
static
int
EncoderOpen
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
#ifndef LOADER
int
i_ret
=
EncOpen
(
p_this
);
if
(
i_ret
!=
VLC_SUCCESS
)
return
i_ret
;
#else
/* We can't open it now, because of ldt_keeper or something
* Open/Encode/Close has to be done in the same thread */
int
i
;
/* Probe if we support it */
for
(
i
=
0
;
encoders_table
[
i
].
i_fourcc
!=
0
;
i
++
)
{
if
(
encoders_table
[
i
].
i_fourcc
==
p_enc
->
fmt_out
.
i_codec
)
{
msg_Dbg
(
p_enc
,
"DMO codec for %4.4s may work with dll=%s"
,
(
char
*
)
&
p_enc
->
fmt_out
.
i_codec
,
encoders_table
[
i
].
psz_dll
);
break
;
}
}
p_enc
->
p_sys
=
NULL
;
if
(
!
encoders_table
[
i
].
i_fourcc
)
return
VLC_EGENERIC
;
#endif
/* LOADER */
/* Set callbacks */
p_enc
->
pf_encode_video
=
(
block_t
*
(
*
)(
encoder_t
*
,
picture_t
*
))
EncodeBlock
;
p_enc
->
pf_encode_audio
=
(
block_t
*
(
*
)(
encoder_t
*
,
aout_buffer_t
*
))
EncodeBlock
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* EncoderSetVideoType: configures the input and output types of the dmo
*****************************************************************************/
static
int
EncoderSetVideoType
(
encoder_t
*
p_enc
,
IMediaObject
*
p_dmo
)
{
int
i
,
i_selected
,
i_err
;
DMO_MEDIA_TYPE
dmo_type
;
VIDEOINFOHEADER
vih
,
*
p_vih
;
BITMAPINFOHEADER
*
p_bih
;
/* FIXME */
p_enc
->
fmt_in
.
video
.
i_bits_per_pixel
=
p_enc
->
fmt_out
.
video
.
i_bits_per_pixel
=
12
;
/* Enumerate input format (for debug output) */
i
=
0
;
while
(
!
p_dmo
->
vt
->
GetInputType
(
p_dmo
,
0
,
i
++
,
&
dmo_type
)
)
{
p_vih
=
(
VIDEOINFOHEADER
*
)
dmo_type
.
pbFormat
;
msg_Dbg
(
p_enc
,
"available input chroma: %4.4s"
,
(
char
*
)
&
dmo_type
.
subtype
.
Data1
);
if
(
!
memcmp
(
&
dmo_type
.
subtype
,
&
MEDIASUBTYPE_RGB565
,
16
)
)
msg_Dbg
(
p_enc
,
"-> MEDIASUBTYPE_RGB565"
);
if
(
!
memcmp
(
&
dmo_type
.
subtype
,
&
MEDIASUBTYPE_RGB24
,
16
)
)
msg_Dbg
(
p_enc
,
"-> MEDIASUBTYPE_RGB24"
);
DMOFreeMediaType
(
&
dmo_type
);
}
/* Setup input format */
memset
(
&
dmo_type
,
0
,
sizeof
(
dmo_type
)
);
dmo_type
.
pUnk
=
0
;
memset
(
&
vih
,
0
,
sizeof
(
VIDEOINFOHEADER
)
);
p_bih
=
&
vih
.
bmiHeader
;
p_bih
->
biCompression
=
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
);
p_bih
->
biWidth
=
p_enc
->
fmt_in
.
video
.
i_width
;
p_bih
->
biHeight
=
p_enc
->
fmt_in
.
video
.
i_height
;
p_bih
->
biBitCount
=
p_enc
->
fmt_in
.
video
.
i_bits_per_pixel
;
p_bih
->
biSizeImage
=
p_enc
->
fmt_in
.
video
.
i_width
*
p_enc
->
fmt_in
.
video
.
i_height
*
p_enc
->
fmt_in
.
video
.
i_bits_per_pixel
/
8
;
p_bih
->
biPlanes
=
3
;
p_bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
vih
.
rcSource
.
left
=
vih
.
rcSource
.
top
=
0
;
vih
.
rcSource
.
right
=
p_enc
->
fmt_in
.
video
.
i_width
;
vih
.
rcSource
.
bottom
=
p_enc
->
fmt_in
.
video
.
i_height
;
vih
.
rcTarget
=
vih
.
rcSource
;
dmo_type
.
majortype
=
MEDIATYPE_Video
;
//dmo_type.subtype = MEDIASUBTYPE_RGB24;
dmo_type
.
subtype
=
MEDIASUBTYPE_I420
;
//dmo_type.subtype.Data1 = p_bih->biCompression;
dmo_type
.
formattype
=
FORMAT_VideoInfo
;
dmo_type
.
bFixedSizeSamples
=
TRUE
;
dmo_type
.
bTemporalCompression
=
FALSE
;
dmo_type
.
lSampleSize
=
p_bih
->
biSizeImage
;
dmo_type
.
cbFormat
=
sizeof
(
VIDEOINFOHEADER
);
dmo_type
.
pbFormat
=
(
char
*
)
&
vih
;
if
(
(
i_err
=
p_dmo
->
vt
->
SetInputType
(
p_dmo
,
0
,
&
dmo_type
,
0
)
)
)
{
msg_Err
(
p_enc
,
"can't set DMO input type: %x"
,
i_err
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_enc
,
"successfully set input type"
);
/* Setup output format */
memset
(
&
dmo_type
,
0
,
sizeof
(
dmo_type
)
);
dmo_type
.
pUnk
=
0
;
/* Enumerate output types */
i
=
0
,
i_selected
=
-
1
;
while
(
!
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i
++
,
&
dmo_type
)
)
{
p_vih
=
(
VIDEOINFOHEADER
*
)
dmo_type
.
pbFormat
;
msg_Dbg
(
p_enc
,
"available output codec: %4.4s"
,
(
char
*
)
&
dmo_type
.
subtype
.
Data1
);
if
(
p_vih
->
bmiHeader
.
biCompression
==
p_enc
->
fmt_out
.
i_codec
)
i_selected
=
i
-
1
;
DMOFreeMediaType
(
&
dmo_type
);
}
if
(
i_selected
<
0
)
{
msg_Err
(
p_enc
,
"couldn't find codec: %4.4s"
,
(
char
*
)
&
p_enc
->
fmt_out
.
i_codec
);
return
VLC_EGENERIC
;
}
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i_selected
,
&
dmo_type
);
((
VIDEOINFOHEADER
*
)
dmo_type
.
pbFormat
)
->
dwBitRate
=
p_enc
->
fmt_out
.
i_bitrate
;
i_err
=
p_dmo
->
vt
->
SetOutputType
(
p_dmo
,
0
,
&
dmo_type
,
0
);
DMOFreeMediaType
(
&
dmo_type
);
if
(
i_err
)
{
msg_Err
(
p_enc
,
"can't set DMO output type: %i"
,
i_err
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_enc
,
"successfully set output type"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* EncoderSetAudioType: configures the input and output types of the dmo
*****************************************************************************/
static
int
EncoderSetAudioType
(
encoder_t
*
p_enc
,
IMediaObject
*
p_dmo
)
{
int
i
,
i_selected
,
i_err
;
unsigned
int
i_last_byterate
;
uint16_t
i_tag
;
DMO_MEDIA_TYPE
dmo_type
;
WAVEFORMATEX
*
p_wf
;
/* Setup the format structure */
fourcc_to_wf_tag
(
p_enc
->
fmt_out
.
i_codec
,
&
i_tag
);
if
(
i_tag
==
0
)
return
VLC_EGENERIC
;
p_enc
->
fmt_in
.
audio
.
i_bitspersample
=
16
;
// Forced
/* We first need to choose an output type from the predefined
* list of choices (we cycle through the list to select the best match) */
i
=
0
;
i_selected
=
-
1
;
i_last_byterate
=
0
;
while
(
!
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i
++
,
&
dmo_type
)
)
{
p_wf
=
(
WAVEFORMATEX
*
)
dmo_type
.
pbFormat
;
msg_Dbg
(
p_enc
,
"available format :%i, sample rate: %i, channels: %i, "
"bits per sample: %i, bitrate: %i, blockalign: %i"
,
(
int
)
p_wf
->
wFormatTag
,
(
int
)
p_wf
->
nSamplesPerSec
,
(
int
)
p_wf
->
nChannels
,
(
int
)
p_wf
->
wBitsPerSample
,
(
int
)
p_wf
->
nAvgBytesPerSec
*
8
,
(
int
)
p_wf
->
nBlockAlign
);
if
(
p_wf
->
wFormatTag
==
i_tag
&&
p_wf
->
nSamplesPerSec
==
p_enc
->
fmt_in
.
audio
.
i_rate
&&
p_wf
->
nChannels
==
p_enc
->
fmt_in
.
audio
.
i_channels
&&
p_wf
->
wBitsPerSample
==
p_enc
->
fmt_in
.
audio
.
i_bitspersample
)
{
if
(
(
int
)
p_wf
->
nAvgBytesPerSec
<
p_enc
->
fmt_out
.
i_bitrate
*
110
/
800
/* + 10% */
&&
p_wf
->
nAvgBytesPerSec
>
i_last_byterate
)
{
i_selected
=
i
-
1
;
i_last_byterate
=
p_wf
->
nAvgBytesPerSec
;
msg_Dbg
(
p_enc
,
"selected entry %i (bitrate: %i)"
,
i_selected
,
p_wf
->
nAvgBytesPerSec
*
8
);
}
}
DMOFreeMediaType
(
&
dmo_type
);
}
if
(
i_selected
<
0
)
{
msg_Err
(
p_enc
,
"couldn't find a matching ouput"
);
return
VLC_EGENERIC
;
}
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i_selected
,
&
dmo_type
);
p_wf
=
(
WAVEFORMATEX
*
)
dmo_type
.
pbFormat
;
msg_Dbg
(
p_enc
,
"selected format: %i, sample rate:%i, "
"channels: %i, bits per sample: %i, bitrate: %i, blockalign: %i"
,
(
int
)
p_wf
->
wFormatTag
,
(
int
)
p_wf
->
nSamplesPerSec
,
(
int
)
p_wf
->
nChannels
,
(
int
)
p_wf
->
wBitsPerSample
,
(
int
)
p_wf
->
nAvgBytesPerSec
*
8
,
(
int
)
p_wf
->
nBlockAlign
);
p_enc
->
fmt_out
.
audio
.
i_rate
=
p_wf
->
nSamplesPerSec
;
p_enc
->
fmt_out
.
audio
.
i_channels
=
p_wf
->
nChannels
;
p_enc
->
fmt_out
.
audio
.
i_bitspersample
=
p_wf
->
wBitsPerSample
;
p_enc
->
fmt_out
.
audio
.
i_blockalign
=
p_wf
->
nBlockAlign
;
p_enc
->
fmt_out
.
i_bitrate
=
p_wf
->
nAvgBytesPerSec
*
8
;
if
(
p_wf
->
cbSize
)
{
msg_Dbg
(
p_enc
,
"found cbSize: %i"
,
p_wf
->
cbSize
);
p_enc
->
fmt_out
.
i_extra
=
p_wf
->
cbSize
;
p_enc
->
fmt_out
.
p_extra
=
malloc
(
p_enc
->
fmt_out
.
i_extra
);
memcpy
(
p_enc
->
fmt_out
.
p_extra
,
&
p_wf
[
1
],
p_enc
->
fmt_out
.
i_extra
);
}
i_err
=
p_dmo
->
vt
->
SetOutputType
(
p_dmo
,
0
,
&
dmo_type
,
0
);
DMOFreeMediaType
(
&
dmo_type
);
if
(
i_err
)
{
msg_Err
(
p_enc
,
"can't set DMO output type: %i"
,
i_err
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_enc
,
"successfully set output type"
);
/* Setup the input type */
i
=
0
;
i_selected
=
-
1
;
while
(
!
p_dmo
->
vt
->
GetInputType
(
p_dmo
,
0
,
i
++
,
&
dmo_type
)
)
{
p_wf
=
(
WAVEFORMATEX
*
)
dmo_type
.
pbFormat
;
msg_Dbg
(
p_enc
,
"available format :%i, sample rate: %i, channels: %i, "
"bits per sample: %i, bitrate: %i, blockalign: %i"
,
(
int
)
p_wf
->
wFormatTag
,
(
int
)
p_wf
->
nSamplesPerSec
,
(
int
)
p_wf
->
nChannels
,
(
int
)
p_wf
->
wBitsPerSample
,
(
int
)
p_wf
->
nAvgBytesPerSec
*
8
,
(
int
)
p_wf
->
nBlockAlign
);
if
(
p_wf
->
wFormatTag
==
WAVE_FORMAT_PCM
&&
p_wf
->
nSamplesPerSec
==
p_enc
->
fmt_in
.
audio
.
i_rate
&&
p_wf
->
nChannels
==
p_enc
->
fmt_in
.
audio
.
i_channels
&&
p_wf
->
wBitsPerSample
==
p_enc
->
fmt_in
.
audio
.
i_bitspersample
)
{
i_selected
=
i
-
1
;
}
DMOFreeMediaType
(
&
dmo_type
);
}
if
(
i_selected
<
0
)
{
msg_Err
(
p_enc
,
"couldn't find a matching input"
);
return
VLC_EGENERIC
;
}
p_dmo
->
vt
->
GetInputType
(
p_dmo
,
0
,
i_selected
,
&
dmo_type
);
i_err
=
p_dmo
->
vt
->
SetInputType
(
p_dmo
,
0
,
&
dmo_type
,
0
);
DMOFreeMediaType
(
&
dmo_type
);
if
(
i_err
)
{
msg_Err
(
p_enc
,
"can't set DMO input type: %x"
,
i_err
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_enc
,
"successfully set input type"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* EncOpen: open dmo codec
*****************************************************************************/
static
int
EncOpen
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
encoder_sys_t
*
p_sys
=
NULL
;
IMediaObject
*
p_dmo
=
NULL
;
HINSTANCE
hmsdmo_dll
=
NULL
;
#ifdef LOADER
ldt_fs_t
*
ldt_fs
=
Setup_LDT_Keeper
();
#else
/* Initialize OLE/COM */
CoInitialize
(
0
);
#endif
/* LOADER */
if
(
LoadDMO
(
p_this
,
&
hmsdmo_dll
,
&
p_dmo
,
&
p_enc
->
fmt_out
,
VLC_TRUE
)
!=
VLC_SUCCESS
)
{
hmsdmo_dll
=
0
;
p_dmo
=
0
;
goto
error
;
}
if
(
p_enc
->
fmt_in
.
i_cat
==
VIDEO_ES
)
{
if
(
EncoderSetVideoType
(
p_enc
,
p_dmo
)
!=
VLC_SUCCESS
)
goto
error
;
}
else
{
if
(
EncoderSetAudioType
(
p_enc
,
p_dmo
)
!=
VLC_SUCCESS
)
goto
error
;
}
/* Allocate the memory needed to store the decoder's structure */
if
(
(
p_enc
->
p_sys
=
p_sys
=
(
encoder_sys_t
*
)
malloc
(
sizeof
(
encoder_sys_t
))
)
==
NULL
)
{
msg_Err
(
p_enc
,
"out of memory"
);
goto
error
;
}
p_sys
->
hmsdmo_dll
=
hmsdmo_dll
;
p_sys
->
p_dmo
=
p_dmo
;
#ifdef LOADER
p_sys
->
ldt_fs
=
ldt_fs
;
#endif
/* Find out some properties of the inputput */
{
uint32_t
i_size
,
i_align
,
dum
;
if
(
p_dmo
->
vt
->
GetInputSizeInfo
(
p_dmo
,
0
,
&
i_size
,
&
i_align
,
&
dum
)
)
msg_Err
(
p_enc
,
"GetInputSizeInfo() failed"
);
else
msg_Dbg
(
p_enc
,
"GetInputSizeInfo(): bytes %i, align %i, %i"
,
i_size
,
i_align
,
dum
);
}
/* Find out some properties of the output */
{
uint32_t
i_size
,
i_align
;
p_sys
->
i_min_output
=
0
;
if
(
p_dmo
->
vt
->
GetOutputSizeInfo
(
p_dmo
,
0
,
&
i_size
,
&
i_align
)
)
{
msg_Err
(
p_enc
,
"GetOutputSizeInfo() failed"
);
goto
error
;
}
else
{
msg_Dbg
(
p_enc
,
"GetOutputSizeInfo(): bytes %i, align %i"
,
i_size
,
i_align
);
p_sys
->
i_min_output
=
i_size
;
}
}
/* Set output properties */
p_enc
->
fmt_out
.
i_cat
=
p_enc
->
fmt_out
.
i_cat
;
if
(
p_enc
->
fmt_out
.
i_cat
==
AUDIO_ES
)
date_Init
(
&
p_sys
->
end_date
,
p_enc
->
fmt_out
.
audio
.
i_rate
,
1
);
else
date_Init
(
&
p_sys
->
end_date
,
25
/* FIXME */
,
1
);
return
VLC_SUCCESS
;
error:
if
(
p_dmo
)
p_dmo
->
vt
->
Release
(
(
IUnknown
*
)
p_dmo
);
if
(
hmsdmo_dll
)
FreeLibrary
(
hmsdmo_dll
);
#ifdef LOADER
Restore_LDT_Keeper
(
ldt_fs
);
#else
/* Uninitialize OLE/COM */
CoUninitialize
();
#endif
/* LOADER */
if
(
p_sys
)
free
(
p_sys
);
return
VLC_EGENERIC
;
}
/****************************************************************************
* Encode: the whole thing
****************************************************************************/
static
block_t
*
EncodeBlock
(
encoder_t
*
p_enc
,
void
*
p_data
)
{
encoder_sys_t
*
p_sys
=
p_enc
->
p_sys
;
CMediaBuffer
*
p_in
;
block_t
*
p_chain
=
NULL
;
block_t
*
p_block_in
;
uint32_t
i_status
;
int
i_result
;
mtime_t
i_pts
;
if
(
p_sys
==
NULL
)
{
if
(
EncOpen
(
VLC_OBJECT
(
p_enc
)
)
)
{
msg_Err
(
p_enc
,
"EncOpen failed"
);
return
NULL
;
}
p_sys
=
p_enc
->
p_sys
;
}
if
(
!
p_data
)
return
NULL
;
if
(
p_enc
->
fmt_out
.
i_cat
==
VIDEO_ES
)
{
/* Get picture data */
picture_t
*
p_pic
=
(
picture_t
*
)
p_data
;
int
i_buffer
=
p_enc
->
fmt_in
.
video
.
i_width
*
p_enc
->
fmt_in
.
video
.
i_height
*
p_enc
->
fmt_in
.
video
.
i_bits_per_pixel
/
8
;
msg_Err
(
p_enc
,
"EncOpen bpp: %i, size: %i"
,
p_enc
->
fmt_in
.
video
.
i_bits_per_pixel
,
i_buffer
);
p_block_in
=
block_New
(
p_enc
,
i_buffer
);
// FIXME: Copy stride by stride;
#if 0
memcpy( p_block_in->p_buffer, p_pic->p->p_pixels,
p_block_in->i_buffer );
#else
memset
(
p_block_in
->
p_buffer
,
0
,
p_block_in
->
i_buffer
);
#endif
i_pts
=
p_pic
->
date
;
}
else
{
aout_buffer_t
*
p_aout_buffer
=
(
aout_buffer_t
*
)
p_data
;
p_block_in
=
block_New
(
p_enc
,
p_aout_buffer
->
i_nb_bytes
);
memcpy
(
p_block_in
->
p_buffer
,
p_aout_buffer
->
p_buffer
,
p_block_in
->
i_buffer
);
i_pts
=
p_aout_buffer
->
start_date
;
}
/* Feed input to the DMO */
p_in
=
CMediaBufferCreate
(
p_block_in
,
p_block_in
->
i_buffer
,
VLC_TRUE
);
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessInput
(
p_sys
->
p_dmo
,
0
,
(
IMediaBuffer
*
)
p_in
,
DMO_INPUT_DATA_BUFFERF_TIME
,
i_pts
*
10
,
0
);
p_in
->
vt
->
Release
(
(
IUnknown
*
)
p_in
);
if
(
i_result
==
S_FALSE
)
{
/* No output generated */
#ifdef DMO_DEBUG
msg_Dbg
(
p_enc
,
"ProcessInput(): no output generated "
I64Fd
,
i_pts
);
#endif
return
NULL
;
}
else
if
(
i_result
==
DMO_E_NOTACCEPTING
)
{
/* Need to call ProcessOutput */
msg_Dbg
(
p_enc
,
"ProcessInput(): not accepting"
);
}
else
if
(
i_result
!=
S_OK
)
{
msg_Dbg
(
p_enc
,
"ProcessInput(): failed: %x"
,
i_result
);
return
NULL
;
}
#if DMO_DEBUG
msg_Dbg
(
p_enc
,
"ProcessInput(): success"
);
#endif
/* Get output from the DMO */
while
(
1
)
{
DMO_OUTPUT_DATA_BUFFER
db
;
block_t
*
p_block_out
;
CMediaBuffer
*
p_out
;
p_block_out
=
block_New
(
p_enc
,
p_sys
->
i_min_output
);
p_block_out
->
i_buffer
=
0
;
p_out
=
CMediaBufferCreate
(
p_block_out
,
p_sys
->
i_min_output
,
VLC_FALSE
);
memset
(
&
db
,
0
,
sizeof
(
db
)
);
db
.
pBuffer
=
(
IMediaBuffer
*
)
p_out
;
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessOutput
(
p_sys
->
p_dmo
,
0
,
1
,
&
db
,
&
i_status
);
if
(
i_result
!=
S_OK
)
{
if
(
i_result
!=
S_FALSE
)
msg_Dbg
(
p_enc
,
"ProcessOutput(): failed: %x"
,
i_result
);
#if DMO_DEBUG
else
msg_Dbg
(
p_enc
,
"ProcessOutput(): no output"
);
#endif
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
return
p_chain
;
}
if
(
!
p_block_out
->
i_buffer
)
{
#if DMO_DEBUG
msg_Dbg
(
p_enc
,
"ProcessOutput(): no output (i_buffer_out == 0)"
);
#endif
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
return
p_chain
;
}
if
(
db
.
dwStatus
&
DMO_OUTPUT_DATA_BUFFERF_TIME
)
{
#if DMO_DEBUG
msg_Dbg
(
p_enc
,
"ProcessOutput(): pts: "
I64Fd
", "
I64Fd
,
i_pts
,
db
.
rtTimestamp
/
10
);
#endif
i_pts
=
db
.
rtTimestamp
/
10
;
}
if
(
db
.
dwStatus
&
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH
)
{
p_block_out
->
i_length
=
db
.
rtTimelength
/
10
;
#if DMO_DEBUG
msg_Dbg
(
p_enc
,
"ProcessOutput(): length: "
I64Fd
,
p_block_out
->
i_length
);
#endif
}
p_block_out
->
i_dts
=
p_block_out
->
i_pts
=
i_pts
;
block_ChainAppend
(
&
p_chain
,
p_block_out
);
}
}
/*****************************************************************************
* EncoderClose: close codec
*****************************************************************************/
void
EncoderClose
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
encoder_sys_t
*
p_sys
=
p_enc
->
p_sys
;
if
(
!
p_sys
)
return
;
FreeLibrary
(
p_sys
->
hmsdmo_dll
);
#ifdef LOADER
#if 0
Restore_LDT_Keeper( p_sys->ldt_fs );
#endif
#else
/* Uninitialize OLE/COM */
CoUninitialize
();
#endif
free
(
p_sys
);
}
modules/codec/dmo/dmo.h
View file @
bb7f54bb
...
...
@@ -28,11 +28,13 @@ static const GUID IID_IMediaBuffer = {0x59eff8b9, 0x938c, 0x4a26, {0x82, 0xf2, 0
static
const
GUID
MEDIATYPE_Video
=
{
0x73646976
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
static
const
GUID
MEDIATYPE_Audio
=
{
0x73647561
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
static
const
GUID
MEDIASUBTYPE_PCM
=
{
0x00000001
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
static
const
GUID
MEDIASUBTYPE_VideoInfo
=
{
0x05589f80
,
0xc356
,
0x11ce
,
{
0xbf
,
0x01
,
0x00
,
0xaa
,
0x00
,
0x55
,
0x59
,
0x5a
}};
static
const
GUID
FORMAT_VideoInfo
=
{
0x05589f80
,
0xc356
,
0x11ce
,
{
0xbf
,
0x01
,
0x00
,
0xaa
,
0x00
,
0x55
,
0x59
,
0x5a
}};
static
const
GUID
FORMAT_WaveFormatEx
=
{
0x05589f81
,
0xc356
,
0x11ce
,
{
0xbf
,
0x01
,
0x00
,
0xaa
,
0x00
,
0x55
,
0x59
,
0x5a
}};
static
const
GUID
GUID_NULL
=
{
0x0000
,
0x0000
,
0x0000
,
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
}};
static
const
GUID
MEDIASUBTYPE_I420
=
{
0x30323449
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
static
const
GUID
MEDIASUBTYPE_YV12
=
{
0x32315659
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
static
const
GUID
MEDIASUBTYPE_RGB24
=
{
0xe436eb7d
,
0x524f
,
0x11ce
,
{
0x9f
,
0x53
,
0x00
,
0x20
,
0xaf
,
0x0b
,
0xa7
,
0x70
}};
static
const
GUID
MEDIASUBTYPE_RGB565
=
{
0xe436eb7b
,
0x524f
,
0x11ce
,
{
0x9f
,
0x53
,
0x00
,
0x20
,
0xaf
,
0x0b
,
0xa7
,
0x70
}};
#define IUnknown IUnknownHack
#define IClassFactory IClassFactoryHack
...
...
@@ -47,6 +49,11 @@ typedef struct _IMediaObject IMediaObject;
#endif
#define DMO_INPUT_DATA_BUFFER_SYNCPOINT 1
#define DMO_INPUT_DATA_BUFFERF_TIME 2
#define DMO_INPUT_DATA_BUFFERF_TIMELENGTH 4
#define DMO_OUTPUT_DATA_BUFFER_SYNCPOINT 1
#define DMO_OUTPUT_DATA_BUFFERF_TIME 2
#define DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH 4
#define DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER 1
#define DMO_E_NOTACCEPTING 0x80040204
...
...
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