Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
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 @@
...
@@ -21,6 +21,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
*****************************************************************************/
#define DMO_DEBUG 1
/*****************************************************************************
/*****************************************************************************
* Preamble
* Preamble
*****************************************************************************/
*****************************************************************************/
...
@@ -78,18 +79,32 @@ static int pi_channels_maps[7] =
...
@@ -78,18 +79,32 @@ static int pi_channels_maps[7] =
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
*****************************************************************************/
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
int
DecoderOpen
(
vlc_object_t
*
);
static
int
DecoderOpen
(
vlc_object_t
*
);
static
int
DecOpen
(
vlc_object_t
*
);
static
void
DecoderClose
(
vlc_object_t
*
);
static
void
DecoderClose
(
vlc_object_t
*
);
static
void
*
DecodeBlock
(
decoder_t
*
,
block_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
*
);
static
void
CopyPicture
(
decoder_t
*
,
picture_t
*
,
uint8_t
*
);
vlc_module_begin
();
vlc_module_begin
();
set_description
(
_
(
"DirectMedia Object decoder"
)
);
set_description
(
_
(
"DirectMedia Object decoder"
)
);
add_shortcut
(
"dmo"
);
add_shortcut
(
"dmo"
);
set_capability
(
"decoder"
,
1
);
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
();
vlc_module_end
();
/*****************************************************************************
/*****************************************************************************
...
@@ -107,7 +122,7 @@ struct decoder_sys_t
...
@@ -107,7 +122,7 @@ struct decoder_sys_t
int
i_min_output
;
int
i_min_output
;
uint8_t
*
p_buffer
;
uint8_t
*
p_buffer
;
audio_date_t
end_date
;
date_t
end_date
;
#ifdef LOADER
#ifdef LOADER
ldt_fs_t
*
ldt_fs
;
ldt_fs_t
*
ldt_fs
;
...
@@ -121,12 +136,18 @@ static const GUID guid_wma9 = { 0x27ca0808, 0x01f5, 0x4e7a, { 0x8b, 0x05, 0x87,
...
@@ -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_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
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
;
vlc_fourcc_t
i_fourcc
;
const
char
*
psz_dll
;
const
char
*
psz_dll
;
const
GUID
*
p_guid
;
const
GUID
*
p_guid
;
}
codecs_table
[]
=
}
codec_dll
;
static
const
codec_dll
decoders_table
[]
=
{
{
/* WM3 */
/* WM3 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'3'
),
"wmv9dmod.dll"
,
&
guid_wmv9
},
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'3'
),
"wmv9dmod.dll"
,
&
guid_wmv9
},
...
@@ -138,215 +159,129 @@ static const struct
...
@@ -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
},
{
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
},
{
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
}
{
0
,
NULL
,
NULL
}
};
};
#endif
/* LOADER */
#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
#ifndef LOADER
return
DecoderOpen
(
p_this
);
int
i_ret
=
DecOpen
(
p_this
);
if
(
i_ret
!=
VLC_SUCCESS
)
return
i_ret
;
#else
#else
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
int
i
;
/* We can't open it now, because of ldt_keeper or something
/* We can't open it now, because of ldt_keeper or something
* Open/Decode/Close has to be done in the same thread */
* Open/Decode/Close has to be done in the same thread */
int
i
;
p_dec
->
p_sys
=
NULL
;
p_dec
->
p_sys
=
NULL
;
/* Probe if we support it */
/* 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"
,
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
);
(
char
*
)
&
p_dec
->
fmt_in
.
i_codec
,
decoders_table
[
i
].
psz_dll
);
/* Set callbacks */
break
;
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
;
}
}
}
}
return
VLC_EGENERIC
;
p_dec
->
p_sys
=
NULL
;
if
(
!
decoders_table
[
i
].
i_fourcc
)
return
VLC_EGENERIC
;
#endif
/* LOADER */
#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_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
NULL
;
decoder_sys_t
*
p_sys
=
NULL
;
DMO_PARTIAL_MEDIATYPE
dmo_partial_type
;
DMO_MEDIA_TYPE
dmo_input_type
,
dmo_output_type
;
DMO_MEDIA_TYPE
dmo_input_type
,
dmo_output_type
;
IMediaObject
*
p_dmo
=
NULL
;
IMediaObject
*
p_dmo
=
NULL
;
HINSTANCE
hmsdmo_dll
=
NULL
;
VIDEOINFOHEADER
*
p_vih
=
NULL
;
VIDEOINFOHEADER
*
p_vih
=
NULL
;
WAVEFORMATEX
*
p_wf
=
NULL
;
WAVEFORMATEX
*
p_wf
=
NULL
;
#ifdef LOADER
#ifdef LOADER
ldt_fs_t
*
ldt_fs
=
Setup_LDT_Keeper
();
ldt_fs_t
*
ldt_fs
=
Setup_LDT_Keeper
();
#endif
/* LOADER */
#else
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
;
}
/* Initialize OLE/COM */
/* Initialize OLE/COM */
CoInitialize
(
0
);
CoInitialize
(
0
);
#endif
/* LOADER */
if
(
OurDMOEnum
(
&
GUID_NULL
,
1
/*DMO_ENUMF_INCLUDE_KEYED*/
,
if
(
LoadDMO
(
p_this
,
&
hmsdmo_dll
,
&
p_dmo
,
&
p_dec
->
fmt_in
,
VLC_FALSE
)
1
,
&
dmo_partial_type
,
0
,
NULL
,
&
p_enum_dmo
)
)
!=
VLC_SUCCESS
)
{
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
)
)
{
{
msg_Err
(
p_dec
,
"can't create DMO"
);
hmsdmo_dll
=
0
;
p_dmo
=
0
;
goto
error
;
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 */
/* Setup input format */
memset
(
&
dmo_input_type
,
0
,
sizeof
(
dmo_input_type
)
);
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
;
dmo_input_type
.
pUnk
=
0
;
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
{
{
uint16_t
i_tag
;
int
i_size
=
sizeof
(
WAVEFORMATEX
)
+
p_dec
->
fmt_in
.
i_extra
;
int
i_size
=
sizeof
(
WAVEFORMATEX
)
+
p_dec
->
fmt_in
.
i_extra
;
p_wf
=
malloc
(
i_size
);
p_wf
=
malloc
(
i_size
);
...
@@ -354,7 +289,13 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -354,7 +289,13 @@ static int DecoderOpen( vlc_object_t *p_this )
if
(
p_dec
->
fmt_in
.
i_extra
)
if
(
p_dec
->
fmt_in
.
i_extra
)
memcpy
(
&
p_wf
[
1
],
p_dec
->
fmt_in
.
p_extra
,
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
->
nSamplesPerSec
=
p_dec
->
fmt_in
.
audio
.
i_rate
;
p_wf
->
nChannels
=
p_dec
->
fmt_in
.
audio
.
i_channels
;
p_wf
->
nChannels
=
p_dec
->
fmt_in
.
audio
.
i_channels
;
p_wf
->
wBitsPerSample
=
p_dec
->
fmt_in
.
audio
.
i_bitspersample
;
p_wf
->
wBitsPerSample
=
p_dec
->
fmt_in
.
audio
.
i_bitspersample
;
...
@@ -365,7 +306,6 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -365,7 +306,6 @@ static int DecoderOpen( vlc_object_t *p_this )
dmo_input_type
.
formattype
=
FORMAT_WaveFormatEx
;
dmo_input_type
.
formattype
=
FORMAT_WaveFormatEx
;
dmo_input_type
.
cbFormat
=
i_size
;
dmo_input_type
.
cbFormat
=
i_size
;
dmo_input_type
.
pbFormat
=
(
char
*
)
p_wf
;
dmo_input_type
.
pbFormat
=
(
char
*
)
p_wf
;
dmo_input_type
.
pUnk
=
NULL
;
dmo_input_type
.
bFixedSizeSamples
=
1
;
dmo_input_type
.
bFixedSizeSamples
=
1
;
dmo_input_type
.
bTemporalCompression
=
0
;
dmo_input_type
.
bTemporalCompression
=
0
;
dmo_input_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
dmo_input_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
...
@@ -382,7 +322,7 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -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
);
memcpy
(
&
p_vih
[
1
],
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
p_bih
=
&
p_vih
->
bmiHeader
;
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
->
biWidth
=
p_dec
->
fmt_in
.
video
.
i_width
;
p_bih
->
biHeight
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_bih
->
biHeight
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_bih
->
biBitCount
=
p_dec
->
fmt_in
.
video
.
i_bits_per_pixel
;
p_bih
->
biBitCount
=
p_dec
->
fmt_in
.
video
.
i_bits_per_pixel
;
...
@@ -395,7 +335,10 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -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
->
rcSource
.
bottom
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_vih
->
rcTarget
=
p_vih
->
rcSource
;
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
.
bFixedSizeSamples
=
0
;
dmo_input_type
.
bTemporalCompression
=
1
;
dmo_input_type
.
bTemporalCompression
=
1
;
dmo_input_type
.
cbFormat
=
i_size
;
dmo_input_type
.
cbFormat
=
i_size
;
...
@@ -411,7 +354,6 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -411,7 +354,6 @@ static int DecoderOpen( vlc_object_t *p_this )
/* Setup output format */
/* Setup output format */
memset
(
&
dmo_output_type
,
0
,
sizeof
(
dmo_output_type
)
);
memset
(
&
dmo_output_type
,
0
,
sizeof
(
dmo_output_type
)
);
dmo_output_type
.
majortype
=
dmo_partial_type
.
type
;
dmo_output_type
.
pUnk
=
0
;
dmo_output_type
.
pUnk
=
0
;
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
...
@@ -435,6 +377,7 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -435,6 +377,7 @@ static int DecoderOpen( vlc_object_t *p_this )
p_wf
->
nSamplesPerSec
*
p_wf
->
nBlockAlign
;
p_wf
->
nSamplesPerSec
*
p_wf
->
nBlockAlign
;
p_wf
->
cbSize
=
0
;
p_wf
->
cbSize
=
0
;
dmo_output_type
.
majortype
=
MEDIATYPE_Audio
;
dmo_output_type
.
formattype
=
FORMAT_WaveFormatEx
;
dmo_output_type
.
formattype
=
FORMAT_WaveFormatEx
;
dmo_output_type
.
subtype
=
MEDIASUBTYPE_PCM
;
dmo_output_type
.
subtype
=
MEDIASUBTYPE_PCM
;
dmo_output_type
.
cbFormat
=
sizeof
(
WAVEFORMATEX
);
dmo_output_type
.
cbFormat
=
sizeof
(
WAVEFORMATEX
);
...
@@ -442,7 +385,6 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -442,7 +385,6 @@ static int DecoderOpen( vlc_object_t *p_this )
dmo_output_type
.
bFixedSizeSamples
=
1
;
dmo_output_type
.
bFixedSizeSamples
=
1
;
dmo_output_type
.
bTemporalCompression
=
0
;
dmo_output_type
.
bTemporalCompression
=
0
;
dmo_output_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
dmo_output_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
dmo_output_type
.
pUnk
=
NULL
;
}
}
else
else
{
{
...
@@ -455,11 +397,11 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -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_aspect
=
VOUT_ASPECT_FACTOR
*
p_dec
->
fmt_out
.
video
.
i_width
/
p_dec
->
fmt_out
.
video
.
i_height
;
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
;
dmo_output_type
.
subtype
=
MEDIASUBTYPE_YV12
;
p_bih
=
&
p_vih
->
bmiHeader
;
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
->
biHeight
*=
-
1
;
p_bih
->
biBitCount
=
p_dec
->
fmt_out
.
video
.
i_bits_per_pixel
;
p_bih
->
biBitCount
=
p_dec
->
fmt_out
.
video
.
i_bits_per_pixel
;
p_bih
->
biSizeImage
=
p_dec
->
fmt_in
.
video
.
i_width
*
p_bih
->
biSizeImage
=
p_dec
->
fmt_in
.
video
.
i_width
*
...
@@ -469,6 +411,7 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -469,6 +411,7 @@ static int DecoderOpen( vlc_object_t *p_this )
//p_bih->biPlanes = 1;
//p_bih->biPlanes = 1;
p_bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
p_bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
dmo_output_type
.
majortype
=
MEDIATYPE_Video
;
dmo_output_type
.
bFixedSizeSamples
=
VLC_TRUE
;
dmo_output_type
.
bFixedSizeSamples
=
VLC_TRUE
;
dmo_output_type
.
bTemporalCompression
=
0
;
dmo_output_type
.
bTemporalCompression
=
0
;
dmo_output_type
.
lSampleSize
=
p_bih
->
biSizeImage
;
dmo_output_type
.
lSampleSize
=
p_bih
->
biSizeImage
;
...
@@ -476,6 +419,7 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -476,6 +419,7 @@ static int DecoderOpen( vlc_object_t *p_this )
dmo_output_type
.
pbFormat
=
(
char
*
)
p_vih
;
dmo_output_type
.
pbFormat
=
(
char
*
)
p_vih
;
}
}
#ifdef DMO_DEBUG
/* Enumerate output types */
/* Enumerate output types */
if
(
p_dec
->
fmt_in
.
i_cat
==
VIDEO_ES
)
if
(
p_dec
->
fmt_in
.
i_cat
==
VIDEO_ES
)
{
{
...
@@ -486,25 +430,10 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -486,25 +430,10 @@ static int DecoderOpen( vlc_object_t *p_this )
{
{
msg_Dbg
(
p_dec
,
"available output chroma: %4.4s"
,
msg_Dbg
(
p_dec
,
"available output chroma: %4.4s"
,
(
char
*
)
&
mt
.
subtype
.
Data1
);
(
char
*
)
&
mt
.
subtype
.
Data1
);
DMOFreeMediaType
(
&
mt
);
}
}
}
}
#endif
/* 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
;
}
}
}
if
(
p_dmo
->
vt
->
SetOutputType
(
p_dmo
,
0
,
&
dmo_output_type
,
0
)
)
if
(
p_dmo
->
vt
->
SetOutputType
(
p_dmo
,
0
,
&
dmo_output_type
,
0
)
)
{
{
...
@@ -550,16 +479,9 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -550,16 +479,9 @@ static int DecoderOpen( vlc_object_t *p_this )
/* Set output properties */
/* Set output properties */
p_dec
->
fmt_out
.
i_cat
=
p_dec
->
fmt_in
.
i_cat
;
p_dec
->
fmt_out
.
i_cat
=
p_dec
->
fmt_in
.
i_cat
;
if
(
p_dec
->
fmt_out
.
i_cat
==
AUDIO_ES
)
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
else
aout_DateInit
(
&
p_sys
->
end_date
,
25
/* FIXME */
);
date_Init
(
&
p_sys
->
end_date
,
25
/* FIXME */
,
1
);
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
;
if
(
p_vih
)
free
(
p_vih
);
if
(
p_vih
)
free
(
p_vih
);
if
(
p_wf
)
free
(
p_wf
);
if
(
p_wf
)
free
(
p_wf
);
...
@@ -567,9 +489,16 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -567,9 +489,16 @@ static int DecoderOpen( vlc_object_t *p_this )
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
error:
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 */
/* Uninitialize OLE/COM */
CoUninitialize
();
CoUninitialize
();
FreeLibrary
(
hmsdmo_dll
);
#endif
/* LOADER */
if
(
p_vih
)
free
(
p_vih
);
if
(
p_vih
)
free
(
p_vih
);
if
(
p_wf
)
free
(
p_wf
);
if
(
p_wf
)
free
(
p_wf
);
...
@@ -579,73 +508,239 @@ static int DecoderOpen( vlc_object_t *p_this )
...
@@ -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
;
DMO_PARTIAL_MEDIATYPE
dmo_partial_type
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
int
i_err
;
/* Uninitialize OLE/COM */
CoUninitialize
();
FreeLibrary
(
p_sys
->
hmsdmo_dll
);
#ifndef LOADER
IEnumDMO
*
p_enum_dmo
=
NULL
;
WCHAR
*
psz_dmo_name
;
GUID
clsid_dmo
;
#else
#if 0
GETCLASS
GetClass
;
#ifdef LOADER
IClassFactory
*
cFactory
=
NULL
;
Restore_LDT_Keeper( p_sys->ldt_fs );
IUnknown
*
cObject
=
NULL
;
#endif
codec_dll
*
codecs_table
=
b_out
?
encoders_table
:
decoders_table
;
int
i_codec
;
#endif
#endif
if
(
p_sys
->
p_buffer
)
free
(
p_sys
->
p_buffer
);
/* Look for a DMO which can handle the requested codec */
free
(
p_sys
);
if
(
p_fmt
->
i_cat
==
AUDIO_ES
)
}
/****************************************************************************
* 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
)
)
)
{
{
msg_Err
(
p_dec
,
"DecoderOpen failed"
);
uint16_t
i_tag
;
return
NULL
;
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
;
#ifndef LOADER
long
(
STDCALL
*
OurDMOEnum
)(
const
GUID
*
,
uint32_t
,
uint32_t
,
p_block
=
*
pp_block
;
const
DMO_PARTIAL_MEDIATYPE
*
,
uint32_t
,
const
DMO_PARTIAL_MEDIATYPE
*
,
/* Won't work with streams with B-frames, but do we have any ? */
IEnumDMO
**
);
if
(
p_block
&&
p_block
->
i_pts
<=
0
)
p_block
->
i_pts
=
p_block
->
i_dts
;
/* Date management */
/* Load msdmo DLL */
if
(
p_block
&&
p_block
->
i_pts
>
0
&&
*
p_hmsdmo_dll
=
LoadLibrary
(
"msdmo.dll"
);
p_block
->
i_pts
!=
aout_DateGet
(
&
p_sys
->
end_date
)
)
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
(
!
b_out
)
if( !aout_DateGet( &p_sys->end_date ) )
{
{
/* 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 );
if( p_block ) block_Release( p_block );
return NULL;
return NULL;
}
}
...
@@ -695,13 +790,11 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
...
@@ -695,13 +790,11 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
}
/* Get output from the DMO */
/* 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
;
block_out
.
i_buffer
=
0
;
p_out
=
CMediaBufferCreate
(
&
block_out
,
p_sys
->
i_min_output
,
VLC_FALSE
);
p_out
=
CMediaBufferCreate
(
&
block_out
,
p_sys
->
i_min_output
,
VLC_FALSE
);
db
.
rtTimestamp
=
0
;
memset
(
&
db
,
0
,
sizeof
(
db
)
);
db
.
rtTimelength
=
0
;
db
.
dwStatus
=
0
;
db
.
pBuffer
=
(
IMediaBuffer
*
)
p_out
;
db
.
pBuffer
=
(
IMediaBuffer
*
)
p_out
;
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessOutput
(
p_sys
->
p_dmo
,
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 )
...
@@ -725,16 +818,7 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
msg_Dbg
(
p_dec
,
"ProcessOutput(): success"
);
msg_Dbg
(
p_dec
,
"ProcessOutput(): success"
);
#endif
#endif
i_result
=
p_out
->
vt
->
GetBufferAndLength
(
(
IMediaBuffer
*
)
p_out
,
if
(
!
block_out
.
i_buffer
)
&
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 DMO_DEBUG
#if DMO_DEBUG
msg_Dbg
(
p_dec
,
"ProcessOutput(): no output (i_buffer_out == 0)"
);
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 )
...
@@ -752,8 +836,8 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
CopyPicture
(
p_dec
,
p_pic
,
block_out
.
p_buffer
);
CopyPicture
(
p_dec
,
p_pic
,
block_out
.
p_buffer
);
/* Date management */
/* Date management */
p_pic
->
date
=
aout_DateGet
(
&
p_sys
->
end_date
);
p_pic
->
date
=
date_Get
(
&
p_sys
->
end_date
);
aout_DateIncrement
(
&
p_sys
->
end_date
,
1
);
date_Increment
(
&
p_sys
->
end_date
,
1
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
...
@@ -762,17 +846,18 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
...
@@ -762,17 +846,18 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
else
else
{
{
aout_buffer_t
*
p_aout_buffer
;
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_bitspersample
*
p_dec
->
fmt_out
.
audio
.
i_channels
/
8
);
p_dec
->
fmt_out
.
audio
.
i_channels
/
8
);
p_aout_buffer
=
p_dec
->
pf_aout_buffer_new
(
p_dec
,
i_samples
);
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 */
/* 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
=
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
);
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 )
...
@@ -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
[
1
].
p_pixels
=
p_pic
->
p
[
2
].
p_pixels
;
p_pic
->
p
[
2
].
p_pixels
=
p_dst
;
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
...
@@ -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_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
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_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
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
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_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_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 IUnknown IUnknownHack
#define IClassFactory IClassFactoryHack
#define IClassFactory IClassFactoryHack
...
@@ -47,6 +49,11 @@ typedef struct _IMediaObject IMediaObject;
...
@@ -47,6 +49,11 @@ typedef struct _IMediaObject IMediaObject;
#endif
#endif
#define DMO_INPUT_DATA_BUFFER_SYNCPOINT 1
#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_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER 1
#define DMO_E_NOTACCEPTING 0x80040204
#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