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
Hide 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
/*****************************************************************************
/*****************************************************************************
* dmo.c : DirectMedia Object decoder module for vlc
* dmo.c : DirectMedia Object decoder module for vlc
*****************************************************************************
*****************************************************************************
* Copyright (C) 2002, 2003 VideoLAN
* Copyright (C) 2002, 2003 VideoLAN
* $Id$
* $Id$
*
*
* Author: Gildas Bazin <gbazin@videolan.org>
* Author: Gildas Bazin <gbazin@videolan.org>
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software
* 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
#include <stdlib.h>
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <vlc/vout.h>
#ifndef WIN32
# define LOADER
#ifndef WIN32
#else
# define LOADER
# include <objbase.h>
#else
#endif
# include <objbase.h>
#endif
#ifdef LOADER
/* Need the w32dll loader from mplayer */
#ifdef LOADER
# include <wine/winerror.h>
/* Need the w32dll loader from mplayer */
# include <ldt_keeper.h>
# include <wine/winerror.h>
# include <wine/windef.h>
# include <ldt_keeper.h>
#endif
# include <wine/windef.h>
#endif
#include "codecs.h"
#include "dmo.h"
#include "codecs.h"
#include "dmo.h"
#ifdef LOADER
/* Not Needed */
#ifdef LOADER
long
CoInitialize
(
void
*
pvReserved
)
{
return
-
1
;
}
/* Not Needed */
void
CoUninitialize
(
void
)
{
}
long
CoInitialize
(
void
*
pvReserved
)
{
return
-
1
;
}
void
CoUninitialize
(
void
)
{
}
/* A few prototypes */
HMODULE
WINAPI
LoadLibraryA
(
LPCSTR
);
/* A few prototypes */
#define LoadLibrary LoadLibraryA
HMODULE
WINAPI
LoadLibraryA
(
LPCSTR
);
FARPROC
WINAPI
GetProcAddress
(
HMODULE
,
LPCSTR
);
#define LoadLibrary LoadLibraryA
int
WINAPI
FreeLibrary
(
HMODULE
);
FARPROC
WINAPI
GetProcAddress
(
HMODULE
,
LPCSTR
);
typedef
long
STDCALL
(
*
GETCLASS
)
(
const
GUID
*
,
const
GUID
*
,
void
**
);
int
WINAPI
FreeLibrary
(
HMODULE
);
#endif
/* LOADER */
typedef
long
STDCALL
(
*
GETCLASS
)
(
const
GUID
*
,
const
GUID
*
,
void
**
);
#endif
/* LOADER */
static
int
pi_channels_maps
[
7
]
=
{
static
int
pi_channels_maps
[
7
]
=
0
,
{
AOUT_CHAN_CENTER
,
0
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
,
AOUT_CHAN_CENTER
,
AOUT_CHAN_CENTER
|
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_REARLEFT
AOUT_CHAN_CENTER
|
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
,
|
AOUT_CHAN_REARRIGHT
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_REARLEFT
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
|
AOUT_CHAN_REARRIGHT
,
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
,
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
,
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
|
AOUT_CHAN_LFE
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
};
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
|
AOUT_CHAN_LFE
};
/*****************************************************************************
* Module descriptor
/*****************************************************************************
*****************************************************************************/
* Module descriptor
static
int
Open
(
vlc_object_t
*
);
*****************************************************************************/
static
int
DecoderOpen
(
vlc_object_t
*
);
static
int
DecoderOpen
(
vlc_object_t
*
);
static
void
DecoderClose
(
vlc_object_t
*
);
static
int
DecOpen
(
vlc_object_t
*
);
static
void
*
DecodeBlock
(
decoder_t
*
,
block_t
**
);
static
void
DecoderClose
(
vlc_object_t
*
);
static
void
*
DecodeBlock
(
decoder_t
*
,
block_t
**
);
static
void
CopyPicture
(
decoder_t
*
,
picture_t
*
,
uint8_t
*
);
static
int
EncoderOpen
(
vlc_object_t
*
);
vlc_module_begin
();
static
int
EncOpen
(
vlc_object_t
*
);
set_description
(
_
(
"DirectMedia Object decoder"
)
);
static
void
EncoderClose
(
vlc_object_t
*
);
add_shortcut
(
"dmo"
);
static
block_t
*
EncodeBlock
(
encoder_t
*
,
void
*
);
set_capability
(
"decoder"
,
1
);
set_callbacks
(
Open
,
DecoderClose
);
static
int
LoadDMO
(
vlc_object_t
*
,
HINSTANCE
*
,
IMediaObject
**
,
vlc_module_end
();
es_format_t
*
,
vlc_bool_t
);
static
void
CopyPicture
(
decoder_t
*
,
picture_t
*
,
uint8_t
*
);
/*****************************************************************************
* Local prototypes
vlc_module_begin
();
*****************************************************************************/
set_description
(
_
(
"DirectMedia Object decoder"
)
);
add_shortcut
(
"dmo"
);
/****************************************************************************
set_capability
(
"decoder"
,
1
);
* Decoder descriptor declaration
set_callbacks
(
DecoderOpen
,
DecoderClose
);
****************************************************************************/
struct
decoder_sys_t
# define ENC_CFG_PREFIX "sout-dmo-"
{
add_submodule
();
HINSTANCE
hmsdmo_dll
;
set_description
(
_
(
"DirectMedia Object encoder"
)
);
IMediaObject
*
p_dmo
;
set_capability
(
"encoder"
,
10
);
set_callbacks
(
EncoderOpen
,
EncoderClose
);
int
i_min_output
;
uint8_t
*
p_buffer
;
vlc_module_end
();
audio_date_t
end_date
;
/*****************************************************************************
* Local prototypes
#ifdef LOADER
*****************************************************************************/
ldt_fs_t
*
ldt_fs
;
#endif
/****************************************************************************
};
* Decoder descriptor declaration
****************************************************************************/
#ifdef LOADER
struct
decoder_sys_t
static
const
GUID
guid_wmv9
=
{
0x724bb6a4
,
0xe526
,
0x450f
,
{
0xaf
,
0xfa
,
0xab
,
0x9b
,
0x45
,
0x12
,
0x91
,
0x11
}
};
{
static
const
GUID
guid_wma9
=
{
0x27ca0808
,
0x01f5
,
0x4e7a
,
{
0x8b
,
0x05
,
0x87
,
0xf8
,
0x07
,
0xa2
,
0x33
,
0xd1
}
};
HINSTANCE
hmsdmo_dll
;
IMediaObject
*
p_dmo
;
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
}
};
int
i_min_output
;
uint8_t
*
p_buffer
;
static
const
struct
{
date_t
end_date
;
vlc_fourcc_t
i_fourcc
;
const
char
*
psz_dll
;
#ifdef LOADER
const
GUID
*
p_guid
;
ldt_fs_t
*
ldt_fs
;
}
codecs_table
[]
=
#endif
{
};
/* WM3 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'3'
),
"wmv9dmod.dll"
,
&
guid_wmv9
},
#ifdef LOADER
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'3'
),
"wmv9dmod.dll"
,
&
guid_wmv9
},
static
const
GUID
guid_wmv9
=
{
0x724bb6a4
,
0xe526
,
0x450f
,
{
0xaf
,
0xfa
,
0xab
,
0x9b
,
0x45
,
0x12
,
0x91
,
0x11
}
};
/* WMV2 */
static
const
GUID
guid_wma9
=
{
0x27ca0808
,
0x01f5
,
0x4e7a
,
{
0x8b
,
0x05
,
0x87
,
0xf8
,
0x07
,
0xa2
,
0x33
,
0xd1
}
};
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'2'
),
"wmvdmod.dll"
,
&
guid_wmv
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'2'
),
"wmvdmod.dll"
,
&
guid_wmv
},
static
const
GUID
guid_wmv
=
{
0x82d353df
,
0x90bd
,
0x4382
,
{
0x8b
,
0xc2
,
0x3f
,
0x61
,
0x92
,
0xb7
,
0x6e
,
0x34
}
};
/* WMV1 */
static
const
GUID
guid_wma
=
{
0x874131cb
,
0x4ecc
,
0x443b
,
{
0x89
,
0x48
,
0x74
,
0x6b
,
0x89
,
0x59
,
0x5d
,
0x20
}
};
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'1'
),
"wmvdmod.dll"
,
&
guid_wmv
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'1'
),
"wmvdmod.dll"
,
&
guid_wmv
},
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
}
};
/* WMA 3*/
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'3'
),
"wma9dmod.dll"
,
&
guid_wma9
},
typedef
struct
{
VLC_FOURCC
(
'w'
,
'm'
,
'a'
,
'3'
),
"wma9dmod.dll"
,
&
guid_wma9
},
{
vlc_fourcc_t
i_fourcc
;
/* */
const
char
*
psz_dll
;
{
0
,
NULL
,
NULL
}
const
GUID
*
p_guid
;
};
#endif
/* LOADER */
}
codec_dll
;
/*****************************************************************************
static
const
codec_dll
decoders_table
[]
=
* Open: open dmo codec
{
*****************************************************************************/
/* WM3 */
static
int
Open
(
vlc_object_t
*
p_this
)
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'3'
),
"wmv9dmod.dll"
,
&
guid_wmv9
},
{
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'3'
),
"wmv9dmod.dll"
,
&
guid_wmv9
},
#ifndef LOADER
/* WMV2 */
return
DecoderOpen
(
p_this
);
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'2'
),
"wmvdmod.dll"
,
&
guid_wmv
},
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'2'
),
"wmvdmod.dll"
,
&
guid_wmv
},
#else
/* WMV1 */
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'1'
),
"wmvdmod.dll"
,
&
guid_wmv
},
int
i
;
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'1'
),
"wmvdmod.dll"
,
&
guid_wmv
},
/* We can't open it now, because of ldt_keeper or something
* Open/Decode/Close has to be done in the same thread */
/* WMA 3 */
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'3'
),
"wma9dmod.dll"
,
&
guid_wma9
},
p_dec
->
p_sys
=
NULL
;
{
VLC_FOURCC
(
'w'
,
'm'
,
'a'
,
'3'
),
"wma9dmod.dll"
,
&
guid_wma9
},
/* WMA 2 */
/* Probe if we support it */
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'2'
),
"wma9dmod.dll"
,
&
guid_wma9
},
for
(
i
=
0
;
codecs_table
[
i
].
i_fourcc
!=
0
;
i
++
)
{
VLC_FOURCC
(
'w'
,
'm'
,
'a'
,
'2'
),
"wma9dmod.dll"
,
&
guid_wma9
},
{
if
(
codecs_table
[
i
].
i_fourcc
==
p_dec
->
fmt_in
.
i_codec
)
/* */
{
{
0
,
NULL
,
NULL
}
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
);
static
const
codec_dll
encoders_table
[]
=
/* Set callbacks */
{
p_dec
->
pf_decode_video
=
/* WMV2 */
(
picture_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'2'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
p_dec
->
pf_decode_audio
=
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'1'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
(
aout_buffer_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
DecodeBlock
;
/* WMV1 */
return
VLC_SUCCESS
;
{
VLC_FOURCC
(
'W'
,
'M'
,
'V'
,
'1'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
}
{
VLC_FOURCC
(
'w'
,
'm'
,
'v'
,
'1'
),
"wmvdmoe.dll"
,
&
guid_wmv_enc
},
}
/* WMA 3 */
return
VLC_EGENERIC
;
{
VLC_FOURCC
(
'W'
,
'M'
,
'A'
,
'3'
),
"wmadmoe.dll"
,
&
guid_wma_enc
},
#endif
/* LOADER */
{
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
},
* DecoderOpen: open dmo codec
*****************************************************************************/
/* */
static
int
DecoderOpen
(
vlc_object_t
*
p_this
)
{
0
,
NULL
,
NULL
}
{
};
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
NULL
;
#endif
/* LOADER */
DMO_PARTIAL_MEDIATYPE
dmo_partial_type
;
static
void
WINAPI
DMOFreeMediaType
(
DMO_MEDIA_TYPE
*
mt
)
DMO_MEDIA_TYPE
dmo_input_type
,
dmo_output_type
;
{
IMediaObject
*
p_dmo
=
NULL
;
if
(
mt
->
cbFormat
!=
0
)
CoTaskMemFree
(
(
PVOID
)
mt
->
pbFormat
);
if
(
mt
->
pUnk
!=
NULL
)
mt
->
pUnk
->
vt
->
Release
(
(
IUnknown
*
)
mt
->
pUnk
);
VIDEOINFOHEADER
*
p_vih
=
NULL
;
mt
->
cbFormat
=
0
;
WAVEFORMATEX
*
p_wf
=
NULL
;
mt
->
pbFormat
=
NULL
;
mt
->
pUnk
=
NULL
;
#ifdef LOADER
}
ldt_fs_t
*
ldt_fs
=
Setup_LDT_Keeper
();
#endif
/* LOADER */
/*****************************************************************************
* DecoderOpen: open dmo codec
HINSTANCE
hmsdmo_dll
=
NULL
;
*****************************************************************************/
static
int
DecoderOpen
(
vlc_object_t
*
p_this
)
/* Look for a DMO which can handle the requested codec */
{
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
{
uint16_t
i_tag
;
#ifndef LOADER
dmo_partial_type
.
type
=
MEDIATYPE_Audio
;
int
i_ret
=
DecOpen
(
p_this
);
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
if
(
i_ret
!=
VLC_SUCCESS
)
return
i_ret
;
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
}
/* We can't open it now, because of ldt_keeper or something
else
* Open/Decode/Close has to be done in the same thread */
{
int
i
;
dmo_partial_type
.
type
=
MEDIATYPE_Video
;
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
p_dec
->
p_sys
=
NULL
;
dmo_partial_type
.
subtype
.
Data1
=
p_dec
->
fmt_in
.
i_codec
;
}
/* Probe if we support it */
for
(
i
=
0
;
decoders_table
[
i
].
i_fourcc
!=
0
;
i
++
)
#ifndef LOADER
{
{
if
(
decoders_table
[
i
].
i_fourcc
==
p_dec
->
fmt_in
.
i_codec
)
IEnumDMO
*
p_enum_dmo
=
NULL
;
{
WCHAR
*
psz_dmo_name
;
msg_Dbg
(
p_dec
,
"DMO codec for %4.4s may work with dll=%s"
,
GUID
clsid_dmo
;
(
char
*
)
&
p_dec
->
fmt_in
.
i_codec
,
long
(
STDCALL
*
OurDMOEnum
)(
const
GUID
*
,
uint32_t
,
uint32_t
,
decoders_table
[
i
].
psz_dll
);
const
DMO_PARTIAL_MEDIATYPE
*
,
break
;
uint32_t
,
const
DMO_PARTIAL_MEDIATYPE
*
,
}
IEnumDMO
**
);
}
/* Load msdmo DLL */
p_dec
->
p_sys
=
NULL
;
hmsdmo_dll
=
LoadLibrary
(
"msdmo.dll"
);
if
(
!
decoders_table
[
i
].
i_fourcc
)
return
VLC_EGENERIC
;
if
(
hmsdmo_dll
==
NULL
)
#endif
/* LOADER */
{
msg_Dbg
(
p_dec
,
"failed loading msdmo.dll"
);
/* Set callbacks */
return
VLC_EGENERIC
;
p_dec
->
pf_decode_video
=
(
picture_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
}
DecodeBlock
;
OurDMOEnum
=
(
void
*
)
GetProcAddress
(
hmsdmo_dll
,
"DMOEnum"
);
p_dec
->
pf_decode_audio
=
(
aout_buffer_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
if
(
OurDMOEnum
==
NULL
)
DecodeBlock
;
{
msg_Dbg
(
p_dec
,
"GetProcAddress failed to find DMOEnum()"
);
return
VLC_SUCCESS
;
FreeLibrary
(
hmsdmo_dll
);
}
return
VLC_EGENERIC
;
}
/*****************************************************************************
* DecOpen: open dmo codec
*****************************************************************************/
/* Initialize OLE/COM */
static
int
DecOpen
(
vlc_object_t
*
p_this
)
CoInitialize
(
0
);
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
if
(
OurDMOEnum
(
&
GUID_NULL
,
1
/*DMO_ENUMF_INCLUDE_KEYED*/
,
decoder_sys_t
*
p_sys
=
NULL
;
1
,
&
dmo_partial_type
,
0
,
NULL
,
&
p_enum_dmo
)
)
{
DMO_MEDIA_TYPE
dmo_input_type
,
dmo_output_type
;
goto
error
;
IMediaObject
*
p_dmo
=
NULL
;
}
HINSTANCE
hmsdmo_dll
=
NULL
;
/* Pickup the first available codec */
VIDEOINFOHEADER
*
p_vih
=
NULL
;
if
(
p_enum_dmo
->
vt
->
Next
(
p_enum_dmo
,
1
,
&
clsid_dmo
,
WAVEFORMATEX
*
p_wf
=
NULL
;
&
psz_dmo_name
,
NULL
)
)
{
#ifdef LOADER
goto
error
;
ldt_fs_t
*
ldt_fs
=
Setup_LDT_Keeper
();
}
#else
p_enum_dmo
->
vt
->
Release
(
(
IUnknown
*
)
p_enum_dmo
);
/* Initialize OLE/COM */
CoInitialize
(
0
);
#if 1
#endif
/* LOADER */
{
char
psz_temp
[
MAX_PATH
];
if
(
LoadDMO
(
p_this
,
&
hmsdmo_dll
,
&
p_dmo
,
&
p_dec
->
fmt_in
,
VLC_FALSE
)
wcstombs
(
psz_temp
,
psz_dmo_name
,
MAX_PATH
);
!=
VLC_SUCCESS
)
msg_Dbg
(
p_dec
,
"found DMO: %s"
,
psz_temp
);
{
}
hmsdmo_dll
=
0
;
#endif
p_dmo
=
0
;
goto
error
;
CoTaskMemFree
(
psz_dmo_name
);
}
/* Create DMO */
/* Setup input format */
if
(
CoCreateInstance
(
&
clsid_dmo
,
NULL
,
CLSCTX_INPROC
,
memset
(
&
dmo_input_type
,
0
,
sizeof
(
dmo_input_type
)
);
&
IID_IMediaObject
,
(
void
**
)
&
p_dmo
)
)
dmo_input_type
.
pUnk
=
0
;
{
msg_Err
(
p_dec
,
"can't create DMO"
);
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
goto
error
;
{
}
uint16_t
i_tag
;
}
int
i_size
=
sizeof
(
WAVEFORMATEX
)
+
p_dec
->
fmt_in
.
i_extra
;
p_wf
=
malloc
(
i_size
);
#else
/* LOADER */
{
memset
(
p_wf
,
0
,
sizeof
(
WAVEFORMATEX
)
);
GETCLASS
GetClass
;
if
(
p_dec
->
fmt_in
.
i_extra
)
IClassFactory
*
cFactory
=
NULL
;
memcpy
(
&
p_wf
[
1
],
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
IUnknown
*
cObject
=
NULL
;
dmo_input_type
.
majortype
=
MEDIATYPE_Audio
;
int
i_err
;
dmo_input_type
.
subtype
=
dmo_input_type
.
majortype
;
int
i_codec
;
dmo_input_type
.
subtype
.
Data1
=
p_dec
->
fmt_in
.
i_codec
;
for
(
i_codec
=
0
;
codecs_table
[
i_codec
].
i_fourcc
!=
0
;
i_codec
++
)
fourcc_to_wf_tag
(
p_dec
->
fmt_in
.
i_codec
,
&
i_tag
);
{
if
(
i_tag
)
dmo_input_type
.
subtype
.
Data1
=
i_tag
;
if
(
codecs_table
[
i_codec
].
i_fourcc
==
p_dec
->
fmt_in
.
i_codec
)
break
;
p_wf
->
wFormatTag
=
dmo_input_type
.
subtype
.
Data1
;
}
p_wf
->
nSamplesPerSec
=
p_dec
->
fmt_in
.
audio
.
i_rate
;
if
(
codecs_table
[
i_codec
].
i_fourcc
==
0
)
p_wf
->
nChannels
=
p_dec
->
fmt_in
.
audio
.
i_channels
;
return
VLC_EGENERIC
;
/* Can't happen */
p_wf
->
wBitsPerSample
=
p_dec
->
fmt_in
.
audio
.
i_bitspersample
;
p_wf
->
nBlockAlign
=
p_dec
->
fmt_in
.
audio
.
i_blockalign
;
hmsdmo_dll
=
LoadLibrary
(
codecs_table
[
i_codec
].
psz_dll
);
p_wf
->
nAvgBytesPerSec
=
p_dec
->
fmt_in
.
i_bitrate
/
8
;
if
(
hmsdmo_dll
==
NULL
)
p_wf
->
cbSize
=
p_dec
->
fmt_in
.
i_extra
;
{
msg_Dbg
(
p_dec
,
"failed loading '%s'"
,
codecs_table
[
i_codec
].
psz_dll
);
dmo_input_type
.
formattype
=
FORMAT_WaveFormatEx
;
return
VLC_EGENERIC
;
dmo_input_type
.
cbFormat
=
i_size
;
}
dmo_input_type
.
pbFormat
=
(
char
*
)
p_wf
;
dmo_input_type
.
bFixedSizeSamples
=
1
;
GetClass
=
(
GETCLASS
)
GetProcAddress
(
hmsdmo_dll
,
"DllGetClassObject"
);
dmo_input_type
.
bTemporalCompression
=
0
;
if
(
!
GetClass
)
dmo_input_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
{
}
msg_Dbg
(
p_dec
,
"GetProcAddress failed to find DllGetClassObject()"
);
else
FreeLibrary
(
hmsdmo_dll
);
{
return
VLC_EGENERIC
;
BITMAPINFOHEADER
*
p_bih
;
}
int
i_size
=
sizeof
(
VIDEOINFOHEADER
)
+
p_dec
->
fmt_in
.
i_extra
;
i_err
=
GetClass
(
codecs_table
[
i_codec
].
p_guid
,
&
IID_IClassFactory
,
p_vih
=
malloc
(
i_size
);
(
void
**
)
&
cFactory
);
if
(
i_err
||
cFactory
==
NULL
)
memset
(
p_vih
,
0
,
sizeof
(
VIDEOINFOHEADER
)
);
{
if
(
p_dec
->
fmt_in
.
i_extra
)
msg_Dbg
(
p_dec
,
"no such class object"
);
memcpy
(
&
p_vih
[
1
],
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
FreeLibrary
(
hmsdmo_dll
);
return
VLC_EGENERIC
;
p_bih
=
&
p_vih
->
bmiHeader
;
}
p_bih
->
biCompression
=
p_dec
->
fmt_in
.
i_codec
;
p_bih
->
biWidth
=
p_dec
->
fmt_in
.
video
.
i_width
;
i_err
=
cFactory
->
vt
->
CreateInstance
(
cFactory
,
0
,
&
IID_IUnknown
,
p_bih
->
biHeight
=
p_dec
->
fmt_in
.
video
.
i_height
;
(
void
**
)
&
cObject
);
p_bih
->
biBitCount
=
p_dec
->
fmt_in
.
video
.
i_bits_per_pixel
;
cFactory
->
vt
->
Release
((
IUnknown
*
)
cFactory
);
p_bih
->
biPlanes
=
1
;
if
(
i_err
||
!
cObject
)
p_bih
->
biSize
=
i_size
-
sizeof
(
VIDEOINFOHEADER
)
+
{
sizeof
(
BITMAPINFOHEADER
);
msg_Dbg
(
p_dec
,
"class factory failure"
);
FreeLibrary
(
hmsdmo_dll
);
p_vih
->
rcSource
.
left
=
p_vih
->
rcSource
.
top
=
0
;
return
VLC_EGENERIC
;
p_vih
->
rcSource
.
right
=
p_dec
->
fmt_in
.
video
.
i_width
;
}
p_vih
->
rcSource
.
bottom
=
p_dec
->
fmt_in
.
video
.
i_height
;
i_err
=
cObject
->
vt
->
QueryInterface
(
cObject
,
&
IID_IMediaObject
,
p_vih
->
rcTarget
=
p_vih
->
rcSource
;
(
void
**
)
&
p_dmo
);
cObject
->
vt
->
Release
((
IUnknown
*
)
cObject
);
dmo_input_type
.
majortype
=
MEDIATYPE_Video
;
}
dmo_input_type
.
subtype
=
dmo_input_type
.
majortype
;
#endif
/* LOADER */
dmo_input_type
.
subtype
.
Data1
=
p_dec
->
fmt_in
.
i_codec
;
dmo_input_type
.
formattype
=
FORMAT_VideoInfo
;
/* Setup input format */
dmo_input_type
.
bFixedSizeSamples
=
0
;
memset
(
&
dmo_input_type
,
0
,
sizeof
(
dmo_input_type
)
);
dmo_input_type
.
bTemporalCompression
=
1
;
dmo_input_type
.
majortype
=
dmo_partial_type
.
type
;
dmo_input_type
.
cbFormat
=
i_size
;
dmo_input_type
.
subtype
=
dmo_partial_type
.
subtype
;
dmo_input_type
.
pbFormat
=
(
char
*
)
p_vih
;
dmo_input_type
.
pUnk
=
0
;
}
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
if
(
p_dmo
->
vt
->
SetInputType
(
p_dmo
,
0
,
&
dmo_input_type
,
0
)
)
{
{
int
i_size
=
sizeof
(
WAVEFORMATEX
)
+
p_dec
->
fmt_in
.
i_extra
;
msg_Err
(
p_dec
,
"can't set DMO input type"
);
p_wf
=
malloc
(
i_size
);
goto
error
;
}
memset
(
p_wf
,
0
,
sizeof
(
WAVEFORMATEX
)
);
msg_Dbg
(
p_dec
,
"DMO input type set"
);
if
(
p_dec
->
fmt_in
.
i_extra
)
memcpy
(
&
p_wf
[
1
],
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
/* Setup output format */
memset
(
&
dmo_output_type
,
0
,
sizeof
(
dmo_output_type
)
);
p_wf
->
wFormatTag
=
dmo_partial_type
.
subtype
.
Data1
;
dmo_output_type
.
pUnk
=
0
;
p_wf
->
nSamplesPerSec
=
p_dec
->
fmt_in
.
audio
.
i_rate
;
p_wf
->
nChannels
=
p_dec
->
fmt_in
.
audio
.
i_channels
;
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
p_wf
->
wBitsPerSample
=
p_dec
->
fmt_in
.
audio
.
i_bitspersample
;
{
p_wf
->
nBlockAlign
=
p_dec
->
fmt_in
.
audio
.
i_blockalign
;
/* Setup the format */
p_wf
->
nAvgBytesPerSec
=
p_dec
->
fmt_in
.
i_bitrate
/
8
;
p_dec
->
fmt_out
.
i_codec
=
AOUT_FMT_S16_NE
;
p_wf
->
cbSize
=
p_dec
->
fmt_in
.
i_extra
;
p_dec
->
fmt_out
.
audio
.
i_rate
=
p_dec
->
fmt_in
.
audio
.
i_rate
;
p_dec
->
fmt_out
.
audio
.
i_channels
=
p_dec
->
fmt_in
.
audio
.
i_channels
;
dmo_input_type
.
formattype
=
FORMAT_WaveFormatEx
;
p_dec
->
fmt_out
.
audio
.
i_bitspersample
=
16
;
//p_dec->fmt_in.audio.i_bitspersample; We request 16
dmo_input_type
.
cbFormat
=
i_size
;
p_dec
->
fmt_out
.
audio
.
i_physical_channels
=
dmo_input_type
.
pbFormat
=
(
char
*
)
p_wf
;
p_dec
->
fmt_out
.
audio
.
i_original_channels
=
dmo_input_type
.
pUnk
=
NULL
;
pi_channels_maps
[
p_dec
->
fmt_out
.
audio
.
i_channels
];
dmo_input_type
.
bFixedSizeSamples
=
1
;
dmo_input_type
.
bTemporalCompression
=
0
;
p_wf
->
wFormatTag
=
WAVE_FORMAT_PCM
;
dmo_input_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
p_wf
->
nSamplesPerSec
=
p_dec
->
fmt_out
.
audio
.
i_rate
;
}
p_wf
->
nChannels
=
p_dec
->
fmt_out
.
audio
.
i_channels
;
else
p_wf
->
wBitsPerSample
=
p_dec
->
fmt_out
.
audio
.
i_bitspersample
;
{
p_wf
->
nBlockAlign
=
BITMAPINFOHEADER
*
p_bih
;
p_wf
->
wBitsPerSample
/
8
*
p_wf
->
nChannels
;
p_wf
->
nAvgBytesPerSec
=
int
i_size
=
sizeof
(
VIDEOINFOHEADER
)
+
p_dec
->
fmt_in
.
i_extra
;
p_wf
->
nSamplesPerSec
*
p_wf
->
nBlockAlign
;
p_vih
=
malloc
(
i_size
);
p_wf
->
cbSize
=
0
;
memset
(
p_vih
,
0
,
sizeof
(
VIDEOINFOHEADER
)
);
dmo_output_type
.
majortype
=
MEDIATYPE_Audio
;
if
(
p_dec
->
fmt_in
.
i_extra
)
dmo_output_type
.
formattype
=
FORMAT_WaveFormatEx
;
memcpy
(
&
p_vih
[
1
],
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
dmo_output_type
.
subtype
=
MEDIASUBTYPE_PCM
;
dmo_output_type
.
cbFormat
=
sizeof
(
WAVEFORMATEX
);
p_bih
=
&
p_vih
->
bmiHeader
;
dmo_output_type
.
pbFormat
=
(
char
*
)
p_wf
;
p_bih
->
biCompression
=
dmo_partial_type
.
subtype
.
Data1
;
dmo_output_type
.
bFixedSizeSamples
=
1
;
p_bih
->
biWidth
=
p_dec
->
fmt_in
.
video
.
i_width
;
dmo_output_type
.
bTemporalCompression
=
0
;
p_bih
->
biHeight
=
p_dec
->
fmt_in
.
video
.
i_height
;
dmo_output_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
p_bih
->
biBitCount
=
p_dec
->
fmt_in
.
video
.
i_bits_per_pixel
;
}
p_bih
->
biPlanes
=
1
;
else
p_bih
->
biSize
=
i_size
-
sizeof
(
VIDEOINFOHEADER
)
+
{
sizeof
(
BITMAPINFOHEADER
);
BITMAPINFOHEADER
*
p_bih
;
p_vih
->
rcSource
.
left
=
p_vih
->
rcSource
.
top
=
0
;
p_dec
->
fmt_out
.
i_codec
=
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
);
p_vih
->
rcSource
.
right
=
p_dec
->
fmt_in
.
video
.
i_width
;
p_dec
->
fmt_out
.
video
.
i_width
=
p_dec
->
fmt_in
.
video
.
i_width
;
p_vih
->
rcSource
.
bottom
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_dec
->
fmt_out
.
video
.
i_height
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_vih
->
rcTarget
=
p_vih
->
rcSource
;
p_dec
->
fmt_out
.
video
.
i_bits_per_pixel
=
12
;
p_dec
->
fmt_out
.
video
.
i_aspect
=
VOUT_ASPECT_FACTOR
*
dmo_input_type
.
formattype
=
MEDIASUBTYPE_VideoInfo
;
p_dec
->
fmt_out
.
video
.
i_width
/
p_dec
->
fmt_out
.
video
.
i_height
;
dmo_input_type
.
bFixedSizeSamples
=
0
;
dmo_input_type
.
bTemporalCompression
=
1
;
dmo_output_type
.
formattype
=
FORMAT_VideoInfo
;
dmo_input_type
.
cbFormat
=
i_size
;
dmo_output_type
.
subtype
=
MEDIASUBTYPE_YV12
;
dmo_input_type
.
pbFormat
=
(
char
*
)
p_vih
;
}
p_bih
=
&
p_vih
->
bmiHeader
;
p_bih
->
biCompression
=
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
);
if
(
p_dmo
->
vt
->
SetInputType
(
p_dmo
,
0
,
&
dmo_input_type
,
0
)
)
p_bih
->
biHeight
*=
-
1
;
{
p_bih
->
biBitCount
=
p_dec
->
fmt_out
.
video
.
i_bits_per_pixel
;
msg_Err
(
p_dec
,
"can't set DMO input type"
);
p_bih
->
biSizeImage
=
p_dec
->
fmt_in
.
video
.
i_width
*
goto
error
;
p_dec
->
fmt_in
.
video
.
i_height
*
}
(
p_dec
->
fmt_in
.
video
.
i_bits_per_pixel
+
7
)
/
8
;
msg_Dbg
(
p_dec
,
"DMO input type set"
);
//p_bih->biPlanes = 1;
/* Setup output format */
p_bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
memset
(
&
dmo_output_type
,
0
,
sizeof
(
dmo_output_type
)
);
dmo_output_type
.
majortype
=
dmo_partial_type
.
type
;
dmo_output_type
.
majortype
=
MEDIATYPE_Video
;
dmo_output_type
.
pUnk
=
0
;
dmo_output_type
.
bFixedSizeSamples
=
VLC_TRUE
;
dmo_output_type
.
bTemporalCompression
=
0
;
if
(
p_dec
->
fmt_in
.
i_cat
==
AUDIO_ES
)
dmo_output_type
.
lSampleSize
=
p_bih
->
biSizeImage
;
{
dmo_output_type
.
cbFormat
=
sizeof
(
VIDEOINFOHEADER
);
/* Setup the format */
dmo_output_type
.
pbFormat
=
(
char
*
)
p_vih
;
p_dec
->
fmt_out
.
i_codec
=
AOUT_FMT_S16_NE
;
}
p_dec
->
fmt_out
.
audio
.
i_rate
=
p_dec
->
fmt_in
.
audio
.
i_rate
;
p_dec
->
fmt_out
.
audio
.
i_channels
=
p_dec
->
fmt_in
.
audio
.
i_channels
;
#ifdef DMO_DEBUG
p_dec
->
fmt_out
.
audio
.
i_bitspersample
=
16
;
//p_dec->fmt_in.audio.i_bitspersample; We request 16
/* Enumerate output types */
p_dec
->
fmt_out
.
audio
.
i_physical_channels
=
if
(
p_dec
->
fmt_in
.
i_cat
==
VIDEO_ES
)
p_dec
->
fmt_out
.
audio
.
i_original_channels
=
{
pi_channels_maps
[
p_dec
->
fmt_out
.
audio
.
i_channels
];
int
i
=
0
;
DMO_MEDIA_TYPE
mt
;
p_wf
->
wFormatTag
=
WAVE_FORMAT_PCM
;
p_wf
->
nSamplesPerSec
=
p_dec
->
fmt_out
.
audio
.
i_rate
;
while
(
!
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i
++
,
&
mt
)
)
p_wf
->
nChannels
=
p_dec
->
fmt_out
.
audio
.
i_channels
;
{
p_wf
->
wBitsPerSample
=
p_dec
->
fmt_out
.
audio
.
i_bitspersample
;
msg_Dbg
(
p_dec
,
"available output chroma: %4.4s"
,
p_wf
->
nBlockAlign
=
(
char
*
)
&
mt
.
subtype
.
Data1
);
p_wf
->
wBitsPerSample
/
8
*
p_wf
->
nChannels
;
DMOFreeMediaType
(
&
mt
);
p_wf
->
nAvgBytesPerSec
=
}
p_wf
->
nSamplesPerSec
*
p_wf
->
nBlockAlign
;
}
p_wf
->
cbSize
=
0
;
#endif
dmo_output_type
.
formattype
=
FORMAT_WaveFormatEx
;
if
(
p_dmo
->
vt
->
SetOutputType
(
p_dmo
,
0
,
&
dmo_output_type
,
0
)
)
dmo_output_type
.
subtype
=
MEDIASUBTYPE_PCM
;
{
dmo_output_type
.
cbFormat
=
sizeof
(
WAVEFORMATEX
);
msg_Err
(
p_dec
,
"can't set DMO output type"
);
dmo_output_type
.
pbFormat
=
(
char
*
)
p_wf
;
goto
error
;
dmo_output_type
.
bFixedSizeSamples
=
1
;
}
dmo_output_type
.
bTemporalCompression
=
0
;
msg_Dbg
(
p_dec
,
"DMO output type set"
);
dmo_output_type
.
lSampleSize
=
p_wf
->
nBlockAlign
;
dmo_output_type
.
pUnk
=
NULL
;
/* Allocate the memory needed to store the decoder's structure */
}
if
(
(
p_dec
->
p_sys
=
p_sys
=
else
(
decoder_sys_t
*
)
malloc
(
sizeof
(
decoder_sys_t
))
)
==
NULL
)
{
{
BITMAPINFOHEADER
*
p_bih
;
msg_Err
(
p_dec
,
"out of memory"
);
goto
error
;
p_dec
->
fmt_out
.
i_codec
=
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
);
}
p_dec
->
fmt_out
.
video
.
i_width
=
p_dec
->
fmt_in
.
video
.
i_width
;
p_dec
->
fmt_out
.
video
.
i_height
=
p_dec
->
fmt_in
.
video
.
i_height
;
p_sys
->
hmsdmo_dll
=
hmsdmo_dll
;
p_dec
->
fmt_out
.
video
.
i_bits_per_pixel
=
12
;
p_sys
->
p_dmo
=
p_dmo
;
p_dec
->
fmt_out
.
video
.
i_aspect
=
VOUT_ASPECT_FACTOR
*
#ifdef LOADER
p_dec
->
fmt_out
.
video
.
i_width
/
p_dec
->
fmt_out
.
video
.
i_height
;
p_sys
->
ldt_fs
=
ldt_fs
;
#endif
dmo_output_type
.
formattype
=
MEDIASUBTYPE_VideoInfo
;
dmo_output_type
.
subtype
=
MEDIASUBTYPE_YV12
;
/* Find out some properties of the output */
{
p_bih
=
&
p_vih
->
bmiHeader
;
uint32_t
i_size
,
i_align
;
p_bih
->
biCompression
=
dmo_partial_type
.
subtype
.
Data1
;
p_bih
->
biHeight
*=
-
1
;
p_sys
->
i_min_output
=
0
;
p_bih
->
biBitCount
=
p_dec
->
fmt_out
.
video
.
i_bits_per_pixel
;
if
(
p_dmo
->
vt
->
GetOutputSizeInfo
(
p_dmo
,
0
,
&
i_size
,
&
i_align
)
)
p_bih
->
biSizeImage
=
p_dec
->
fmt_in
.
video
.
i_width
*
{
p_dec
->
fmt_in
.
video
.
i_height
*
msg_Err
(
p_dec
,
"GetOutputSizeInfo() failed"
);
(
p_dec
->
fmt_in
.
video
.
i_bits_per_pixel
+
7
)
/
8
;
goto
error
;
}
//p_bih->biPlanes = 1;
else
p_bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
{
msg_Dbg
(
p_dec
,
"GetOutputSizeInfo(): bytes %i, align %i"
,
dmo_output_type
.
bFixedSizeSamples
=
VLC_TRUE
;
i_size
,
i_align
);
dmo_output_type
.
bTemporalCompression
=
0
;
p_sys
->
i_min_output
=
i_size
;
dmo_output_type
.
lSampleSize
=
p_bih
->
biSizeImage
;
p_sys
->
p_buffer
=
malloc
(
i_size
);
dmo_output_type
.
cbFormat
=
sizeof
(
VIDEOINFOHEADER
);
if
(
!
p_sys
->
p_buffer
)
goto
error
;
dmo_output_type
.
pbFormat
=
(
char
*
)
p_vih
;
}
}
}
/* Enumerate output types */
/* Set output properties */
if
(
p_dec
->
fmt_in
.
i_cat
==
VIDEO_ES
)
p_dec
->
fmt_out
.
i_cat
=
p_dec
->
fmt_in
.
i_cat
;
{
if
(
p_dec
->
fmt_out
.
i_cat
==
AUDIO_ES
)
int
i
=
0
;
date_Init
(
&
p_sys
->
end_date
,
p_dec
->
fmt_in
.
audio
.
i_rate
,
1
);
DMO_MEDIA_TYPE
mt
;
else
date_Init
(
&
p_sys
->
end_date
,
25
/* FIXME */
,
1
);
while
(
!
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i
++
,
&
mt
)
)
{
if
(
p_vih
)
free
(
p_vih
);
msg_Dbg
(
p_dec
,
"available output chroma: %4.4s"
,
if
(
p_wf
)
free
(
p_wf
);
(
char
*
)
&
mt
.
subtype
.
Data1
);
}
return
VLC_SUCCESS
;
}
error:
/* Choose an output type.
* FIXME, get rid of the dmo_output_type code above. */
if
(
p_dmo
)
p_dmo
->
vt
->
Release
(
(
IUnknown
*
)
p_dmo
);
if
(
p_dec
->
fmt_in
.
i_cat
==
VIDEO_ES
)
if
(
hmsdmo_dll
)
FreeLibrary
(
hmsdmo_dll
);
{
int
i
=
0
;
#ifdef LOADER
DMO_MEDIA_TYPE
mt
;
Restore_LDT_Keeper
(
ldt_fs
);
#else
while
(
!
p_dmo
->
vt
->
GetOutputType
(
p_dmo
,
0
,
i
++
,
&
mt
)
)
/* Uninitialize OLE/COM */
{
CoUninitialize
();
if
(
dmo_output_type
.
subtype
.
Data1
==
mt
.
subtype
.
Data1
)
#endif
/* LOADER */
{
*
p_vih
=
*
(
VIDEOINFOHEADER
*
)
mt
.
pbFormat
;
if
(
p_vih
)
free
(
p_vih
);
break
;
if
(
p_wf
)
free
(
p_wf
);
}
if
(
p_sys
)
free
(
p_sys
);
}
}
return
VLC_EGENERIC
;
}
if
(
p_dmo
->
vt
->
SetOutputType
(
p_dmo
,
0
,
&
dmo_output_type
,
0
)
)
{
/*****************************************************************************
msg_Err
(
p_dec
,
"can't set DMO output type"
);
* LoadDMO: Load the DMO object
goto
error
;
*****************************************************************************/
}
static
int
LoadDMO
(
vlc_object_t
*
p_this
,
HINSTANCE
*
p_hmsdmo_dll
,
msg_Dbg
(
p_dec
,
"DMO output type set"
);
IMediaObject
**
pp_dmo
,
es_format_t
*
p_fmt
,
vlc_bool_t
b_out
)
/* Allocate the memory needed to store the decoder's structure */
{
if
(
(
p_dec
->
p_sys
=
p_sys
=
DMO_PARTIAL_MEDIATYPE
dmo_partial_type
;
(
decoder_sys_t
*
)
malloc
(
sizeof
(
decoder_sys_t
))
)
==
NULL
)
int
i_err
;
{
msg_Err
(
p_dec
,
"out of memory"
);
#ifndef LOADER
goto
error
;
IEnumDMO
*
p_enum_dmo
=
NULL
;
}
WCHAR
*
psz_dmo_name
;
GUID
clsid_dmo
;
p_sys
->
hmsdmo_dll
=
hmsdmo_dll
;
#else
p_sys
->
p_dmo
=
p_dmo
;
#ifdef LOADER
GETCLASS
GetClass
;
p_sys
->
ldt_fs
=
ldt_fs
;
IClassFactory
*
cFactory
=
NULL
;
#endif
IUnknown
*
cObject
=
NULL
;
codec_dll
*
codecs_table
=
b_out
?
encoders_table
:
decoders_table
;
/* Find out some properties of the output */
int
i_codec
;
{
#endif
uint32_t
i_size
,
i_align
;
/* Look for a DMO which can handle the requested codec */
p_sys
->
i_min_output
=
0
;
if
(
p_fmt
->
i_cat
==
AUDIO_ES
)
if
(
p_dmo
->
vt
->
GetOutputSizeInfo
(
p_dmo
,
0
,
&
i_size
,
&
i_align
)
)
{
{
uint16_t
i_tag
;
msg_Err
(
p_dec
,
"GetOutputSizeInfo() failed"
);
dmo_partial_type
.
type
=
MEDIATYPE_Audio
;
goto
error
;
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
}
dmo_partial_type
.
subtype
.
Data1
=
p_fmt
->
i_codec
;
else
fourcc_to_wf_tag
(
p_fmt
->
i_codec
,
&
i_tag
);
{
if
(
i_tag
)
dmo_partial_type
.
subtype
.
Data1
=
i_tag
;
msg_Dbg
(
p_dec
,
"GetOutputSizeInfo(): bytes %i, align %i"
,
}
i_size
,
i_align
);
else
p_sys
->
i_min_output
=
i_size
;
{
p_sys
->
p_buffer
=
malloc
(
i_size
);
dmo_partial_type
.
type
=
MEDIATYPE_Video
;
if
(
!
p_sys
->
p_buffer
)
goto
error
;
dmo_partial_type
.
subtype
=
dmo_partial_type
.
type
;
}
dmo_partial_type
.
subtype
.
Data1
=
p_fmt
->
i_codec
;
}
}
/* Set output properties */
#ifndef LOADER
p_dec
->
fmt_out
.
i_cat
=
p_dec
->
fmt_in
.
i_cat
;
long
(
STDCALL
*
OurDMOEnum
)(
const
GUID
*
,
uint32_t
,
uint32_t
,
if
(
p_dec
->
fmt_out
.
i_cat
==
AUDIO_ES
)
const
DMO_PARTIAL_MEDIATYPE
*
,
aout_DateInit
(
&
p_sys
->
end_date
,
p_dec
->
fmt_in
.
audio
.
i_rate
);
uint32_t
,
const
DMO_PARTIAL_MEDIATYPE
*
,
else
IEnumDMO
**
);
aout_DateInit
(
&
p_sys
->
end_date
,
25
/* FIXME */
);
aout_DateSet
(
&
p_sys
->
end_date
,
0
);
/* Load msdmo DLL */
*
p_hmsdmo_dll
=
LoadLibrary
(
"msdmo.dll"
);
/* Set callbacks */
if
(
*
p_hmsdmo_dll
==
NULL
)
p_dec
->
pf_decode_video
=
(
picture_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
{
DecodeBlock
;
msg_Dbg
(
p_this
,
"failed loading msdmo.dll"
);
p_dec
->
pf_decode_audio
=
(
aout_buffer_t
*
(
*
)(
decoder_t
*
,
block_t
**
))
return
VLC_EGENERIC
;
DecodeBlock
;
}
OurDMOEnum
=
(
void
*
)
GetProcAddress
(
*
p_hmsdmo_dll
,
"DMOEnum"
);
if
(
p_vih
)
free
(
p_vih
);
if
(
OurDMOEnum
==
NULL
)
if
(
p_wf
)
free
(
p_wf
);
{
msg_Dbg
(
p_this
,
"GetProcAddress failed to find DMOEnum()"
);
return
VLC_SUCCESS
;
FreeLibrary
(
*
p_hmsdmo_dll
);
return
VLC_EGENERIC
;
error:
}
/* Uninitialize OLE/COM */
CoUninitialize
();
if
(
!
b_out
)
FreeLibrary
(
hmsdmo_dll
);
{
i_err
=
OurDMOEnum
(
&
GUID_NULL
,
1
/*DMO_ENUMF_INCLUDE_KEYED*/
,
if
(
p_vih
)
free
(
p_vih
);
1
,
&
dmo_partial_type
,
0
,
NULL
,
&
p_enum_dmo
);
if
(
p_wf
)
free
(
p_wf
);
}
if
(
p_sys
)
free
(
p_sys
);
else
{
return
VLC_EGENERIC
;
i_err
=
OurDMOEnum
(
&
GUID_NULL
,
1
/*DMO_ENUMF_INCLUDE_KEYED*/
,
}
0
,
NULL
,
1
,
&
dmo_partial_type
,
&
p_enum_dmo
);
}
/*****************************************************************************
if
(
i_err
)
* DecoderClose: close codec
{
*****************************************************************************/
CoUninitialize
();
void
DecoderClose
(
vlc_object_t
*
p_this
)
FreeLibrary
(
*
p_hmsdmo_dll
);
{
return
VLC_EGENERIC
;
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
}
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
/* Pickup the first available codec */
/* Uninitialize OLE/COM */
if
(
p_enum_dmo
->
vt
->
Next
(
p_enum_dmo
,
1
,
&
clsid_dmo
,
CoUninitialize
();
&
psz_dmo_name
,
NULL
)
)
{
FreeLibrary
(
p_sys
->
hmsdmo_dll
);
CoUninitialize
();
FreeLibrary
(
*
p_hmsdmo_dll
);
#if 0
return
VLC_EGENERIC
;
#ifdef LOADER
}
Restore_LDT_Keeper( p_sys->ldt_fs );
p_enum_dmo
->
vt
->
Release
(
(
IUnknown
*
)
p_enum_dmo
);
#endif
#endif
#if 1
{
if
(
p_sys
->
p_buffer
)
free
(
p_sys
->
p_buffer
);
char
psz_temp
[
MAX_PATH
];
free
(
p_sys
);
wcstombs
(
psz_temp
,
psz_dmo_name
,
MAX_PATH
);
}
msg_Dbg
(
p_this
,
"found DMO: %s"
,
psz_temp
);
}
/****************************************************************************
#endif
* DecodeBlock: the whole thing
****************************************************************************
CoTaskMemFree
(
psz_dmo_name
);
* This function must be fed with ogg packets.
****************************************************************************/
/* Create DMO */
static
void
*
DecodeBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
if
(
CoCreateInstance
(
&
clsid_dmo
,
NULL
,
CLSCTX_INPROC
,
{
&
IID_IMediaObject
,
(
void
**
)
pp_dmo
)
)
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
{
block_t
*
p_block
;
msg_Err
(
p_this
,
"can't create DMO"
);
int
i_result
;
CoUninitialize
();
FreeLibrary
(
*
p_hmsdmo_dll
);
DMO_OUTPUT_DATA_BUFFER
db
;
return
VLC_EGENERIC
;
CMediaBuffer
*
p_out
;
}
block_t
block_out
;
uint32_t
i_status
,
i_buffer_out
;
#else
/* LOADER */
uint8_t
*
p_buffer_out
;
for
(
i_codec
=
0
;
codecs_table
[
i_codec
].
i_fourcc
!=
0
;
i_codec
++
)
{
if
(
p_sys
==
NULL
)
if
(
codecs_table
[
i_codec
].
i_fourcc
==
p_fmt
->
i_codec
)
{
break
;
if
(
DecoderOpen
(
VLC_OBJECT
(
p_dec
)
)
)
}
{
if
(
codecs_table
[
i_codec
].
i_fourcc
==
0
)
msg_Err
(
p_dec
,
"DecoderOpen failed"
);
return
VLC_EGENERIC
;
/* Can't happen */
return
NULL
;
}
*
p_hmsdmo_dll
=
LoadLibrary
(
codecs_table
[
i_codec
].
psz_dll
);
p_sys
=
p_dec
->
p_sys
;
if
(
*
p_hmsdmo_dll
==
NULL
)
}
{
msg_Dbg
(
p_this
,
"failed loading '%s'"
,
if
(
!
pp_block
)
return
NULL
;
codecs_table
[
i_codec
].
psz_dll
);
return
VLC_EGENERIC
;
p_block
=
*
pp_block
;
}
/* Won't work with streams with B-frames, but do we have any ? */
GetClass
=
(
GETCLASS
)
GetProcAddress
(
*
p_hmsdmo_dll
,
"DllGetClassObject"
);
if
(
p_block
&&
p_block
->
i_pts
<=
0
)
p_block
->
i_pts
=
p_block
->
i_dts
;
if
(
!
GetClass
)
{
/* Date management */
msg_Dbg
(
p_this
,
"GetProcAddress failed to find DllGetClassObject()"
);
if
(
p_block
&&
p_block
->
i_pts
>
0
&&
FreeLibrary
(
*
p_hmsdmo_dll
);
p_block
->
i_pts
!=
aout_DateGet
(
&
p_sys
->
end_date
)
)
return
VLC_EGENERIC
;
{
}
aout_DateSet
(
&
p_sys
->
end_date
,
p_block
->
i_pts
);
}
i_err
=
GetClass
(
codecs_table
[
i_codec
].
p_guid
,
&
IID_IClassFactory
,
(
void
**
)
&
cFactory
);
#if 0 /* Breaks the video decoding */
if
(
i_err
||
cFactory
==
NULL
)
if( !aout_DateGet( &p_sys->end_date ) )
{
{
msg_Dbg
(
p_this
,
"no such class object"
);
/* We've just started the stream, wait for the first PTS. */
FreeLibrary
(
*
p_hmsdmo_dll
);
if( p_block ) block_Release( p_block );
return
VLC_EGENERIC
;
return NULL;
}
}
#endif
i_err
=
cFactory
->
vt
->
CreateInstance
(
cFactory
,
0
,
&
IID_IUnknown
,
(
void
**
)
&
cObject
);
/* Feed input to the DMO */
cFactory
->
vt
->
Release
(
(
IUnknown
*
)
cFactory
);
if
(
p_block
&&
p_block
->
i_buffer
)
if
(
i_err
||
!
cObject
)
{
{
CMediaBuffer
*
p_in
;
msg_Dbg
(
p_this
,
"class factory failure"
);
FreeLibrary
(
*
p_hmsdmo_dll
);
p_in
=
CMediaBufferCreate
(
p_block
,
p_block
->
i_buffer
,
VLC_TRUE
);
return
VLC_EGENERIC
;
}
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessInput
(
p_sys
->
p_dmo
,
0
,
i_err
=
cObject
->
vt
->
QueryInterface
(
cObject
,
&
IID_IMediaObject
,
(
IMediaBuffer
*
)
p_in
,
DMO_INPUT_DATA_BUFFER_SYNCPOINT
,
(
void
**
)
pp_dmo
);
0
,
0
);
cObject
->
vt
->
Release
(
(
IUnknown
*
)
cObject
);
if
(
i_err
||
!*
pp_dmo
)
p_in
->
vt
->
Release
(
(
IUnknown
*
)
p_in
);
{
msg_Dbg
(
p_this
,
"QueryInterface failure"
);
if
(
i_result
==
S_FALSE
)
FreeLibrary
(
*
p_hmsdmo_dll
);
{
return
VLC_EGENERIC
;
/* No output generated */
}
#ifdef DMO_DEBUG
#endif
/* LOADER */
msg_Dbg
(
p_dec
,
"ProcessInput(): no output generated"
);
#endif
return
VLC_SUCCESS
;
return
NULL
;
}
}
else
if
(
i_result
==
DMO_E_NOTACCEPTING
)
/*****************************************************************************
{
* DecoderClose: close codec
/* Need to call ProcessOutput */
*****************************************************************************/
msg_Dbg
(
p_dec
,
"ProcessInput(): not accepting"
);
void
DecoderClose
(
vlc_object_t
*
p_this
)
}
{
else
if
(
i_result
!=
S_OK
)
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
msg_Dbg
(
p_dec
,
"ProcessInput(): failed"
);
return
NULL
;
if
(
!
p_sys
)
return
;
}
else
FreeLibrary
(
p_sys
->
hmsdmo_dll
);
{
//msg_Dbg( p_dec, "ProcessInput(): successful" );
#ifdef LOADER
*
pp_block
=
0
;
#if 0
}
Restore_LDT_Keeper( p_sys->ldt_fs );
}
#endif
else
if
(
p_block
&&
!
p_block
->
i_buffer
)
#else
{
/* Uninitialize OLE/COM */
block_Release
(
p_block
);
CoUninitialize
();
*
pp_block
=
0
;
#endif
}
if
(
p_sys
->
p_buffer
)
free
(
p_sys
->
p_buffer
);
/* Get output from the DMO */
free
(
p_sys
);
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
);
* DecodeBlock: the whole thing
db
.
rtTimestamp
=
0
;
****************************************************************************
db
.
rtTimelength
=
0
;
* This function must be fed with ogg packets.
db
.
dwStatus
=
0
;
****************************************************************************/
db
.
pBuffer
=
(
IMediaBuffer
*
)
p_out
;
static
void
*
DecodeBlock
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessOutput
(
p_sys
->
p_dmo
,
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER
,
block_t
*
p_block
;
1
,
&
db
,
&
i_status
);
int
i_result
;
if
(
i_result
!=
S_OK
)
DMO_OUTPUT_DATA_BUFFER
db
;
{
CMediaBuffer
*
p_out
;
if
(
i_result
!=
S_FALSE
)
block_t
block_out
;
msg_Dbg
(
p_dec
,
"ProcessOutput(): failed"
);
uint32_t
i_status
;
#if DMO_DEBUG
else
if
(
p_sys
==
NULL
)
msg_Dbg
(
p_dec
,
"ProcessOutput(): no output"
);
{
#endif
if
(
DecOpen
(
VLC_OBJECT
(
p_dec
)
)
)
{
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
msg_Err
(
p_dec
,
"DecOpen failed"
);
return
NULL
;
return
NULL
;
}
}
p_sys
=
p_dec
->
p_sys
;
#if DMO_DEBUG
}
msg_Dbg
(
p_dec
,
"ProcessOutput(): success"
);
#endif
if
(
!
pp_block
)
return
NULL
;
i_result
=
p_out
->
vt
->
GetBufferAndLength
(
(
IMediaBuffer
*
)
p_out
,
p_block
=
*
pp_block
;
&
p_buffer_out
,
&
i_buffer_out
);
if
(
i_result
!=
S_OK
)
/* 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
;
msg_Dbg
(
p_dec
,
"GetBufferAndLength(): failed"
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
/* Date management */
return
NULL
;
if
(
p_block
&&
p_block
->
i_pts
>
0
&&
}
p_block
->
i_pts
!=
date_Get
(
&
p_sys
->
end_date
)
)
{
if
(
!
i_buffer_out
)
date_Set
(
&
p_sys
->
end_date
,
p_block
->
i_pts
);
{
}
#if DMO_DEBUG
msg_Dbg
(
p_dec
,
"ProcessOutput(): no output (i_buffer_out == 0)"
);
#if 0 /* Breaks the video decoding */
#endif
if( !date_Get( &p_sys->end_date ) )
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
{
return
NULL
;
/* We've just started the stream, wait for the first PTS. */
}
if( p_block ) block_Release( p_block );
return NULL;
if
(
p_dec
->
fmt_out
.
i_cat
==
VIDEO_ES
)
}
{
#endif
/* Get a new picture */
picture_t
*
p_pic
=
p_dec
->
pf_vout_buffer_new
(
p_dec
);
/* Feed input to the DMO */
if
(
!
p_pic
)
return
NULL
;
if
(
p_block
&&
p_block
->
i_buffer
)
{
CopyPicture
(
p_dec
,
p_pic
,
block_out
.
p_buffer
);
CMediaBuffer
*
p_in
;
/* Date management */
p_in
=
CMediaBufferCreate
(
p_block
,
p_block
->
i_buffer
,
VLC_TRUE
);
p_pic
->
date
=
aout_DateGet
(
&
p_sys
->
end_date
);
aout_DateIncrement
(
&
p_sys
->
end_date
,
1
);
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessInput
(
p_sys
->
p_dmo
,
0
,
(
IMediaBuffer
*
)
p_in
,
DMO_INPUT_DATA_BUFFER_SYNCPOINT
,
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
0
,
0
);
return
p_pic
;
p_in
->
vt
->
Release
(
(
IUnknown
*
)
p_in
);
}
else
if
(
i_result
==
S_FALSE
)
{
{
aout_buffer_t
*
p_aout_buffer
;
/* No output generated */
int
i_samples
=
i_buffer_out
/
#ifdef DMO_DEBUG
(
p_dec
->
fmt_out
.
audio
.
i_bitspersample
*
msg_Dbg
(
p_dec
,
"ProcessInput(): no output generated"
);
p_dec
->
fmt_out
.
audio
.
i_channels
/
8
);
#endif
return
NULL
;
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
);
else
if
(
i_result
==
DMO_E_NOTACCEPTING
)
{
/* Date management */
/* Need to call ProcessOutput */
p_aout_buffer
->
start_date
=
aout_DateGet
(
&
p_sys
->
end_date
);
msg_Dbg
(
p_dec
,
"ProcessInput(): not accepting"
);
p_aout_buffer
->
end_date
=
}
aout_DateIncrement
(
&
p_sys
->
end_date
,
i_samples
);
else
if
(
i_result
!=
S_OK
)
{
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
msg_Dbg
(
p_dec
,
"ProcessInput(): failed"
);
return
NULL
;
return
p_aout_buffer
;
}
}
else
{
return
NULL
;
//msg_Dbg( p_dec, "ProcessInput(): successful" );
}
*
pp_block
=
0
;
}
static
void
CopyPicture
(
decoder_t
*
p_dec
,
picture_t
*
p_pic
,
uint8_t
*
p_in
)
}
{
else
if
(
p_block
&&
!
p_block
->
i_buffer
)
int
i_plane
,
i_line
,
i_width
,
i_dst_stride
;
{
uint8_t
*
p_dst
,
*
p_src
=
p_in
;
block_Release
(
p_block
);
*
pp_block
=
0
;
p_dst
=
p_pic
->
p
[
1
].
p_pixels
;
}
p_pic
->
p
[
1
].
p_pixels
=
p_pic
->
p
[
2
].
p_pixels
;
p_pic
->
p
[
2
].
p_pixels
=
p_dst
;
/* Get output from the DMO */
block_out
.
p_buffer
=
p_sys
->
p_buffer
;
for
(
i_plane
=
0
;
i_plane
<
p_pic
->
i_planes
;
i_plane
++
)
block_out
.
i_buffer
=
0
;
{
p_dst
=
p_pic
->
p
[
i_plane
].
p_pixels
;
p_out
=
CMediaBufferCreate
(
&
block_out
,
p_sys
->
i_min_output
,
VLC_FALSE
);
i_width
=
p_pic
->
p
[
i_plane
].
i_visible_pitch
;
memset
(
&
db
,
0
,
sizeof
(
db
)
);
i_dst_stride
=
p_pic
->
p
[
i_plane
].
i_pitch
;
db
.
pBuffer
=
(
IMediaBuffer
*
)
p_out
;
for
(
i_line
=
0
;
i_line
<
p_pic
->
p
[
i_plane
].
i_lines
;
i_line
++
)
i_result
=
p_sys
->
p_dmo
->
vt
->
ProcessOutput
(
p_sys
->
p_dmo
,
{
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER
,
p_dec
->
p_vlc
->
pf_memcpy
(
p_dst
,
p_src
,
i_width
);
1
,
&
db
,
&
i_status
);
p_src
+=
i_width
;
p_dst
+=
i_dst_stride
;
if
(
i_result
!=
S_OK
)
}
{
}
if
(
i_result
!=
S_FALSE
)
msg_Dbg
(
p_dec
,
"ProcessOutput(): failed"
);
p_dst
=
p_pic
->
p
[
1
].
p_pixels
;
#if DMO_DEBUG
p_pic
->
p
[
1
].
p_pixels
=
p_pic
->
p
[
2
].
p_pixels
;
else
p_pic
->
p
[
2
].
p_pixels
=
p_dst
;
msg_Dbg
(
p_dec
,
"ProcessOutput(): no output"
);
}
#endif
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
return
NULL
;
}
#if DMO_DEBUG
msg_Dbg
(
p_dec
,
"ProcessOutput(): success"
);
#endif
if
(
!
block_out
.
i_buffer
)
{
#if DMO_DEBUG
msg_Dbg
(
p_dec
,
"ProcessOutput(): no output (i_buffer_out == 0)"
);
#endif
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
return
NULL
;
}
if
(
p_dec
->
fmt_out
.
i_cat
==
VIDEO_ES
)
{
/* Get a new picture */
picture_t
*
p_pic
=
p_dec
->
pf_vout_buffer_new
(
p_dec
);
if
(
!
p_pic
)
return
NULL
;
CopyPicture
(
p_dec
,
p_pic
,
block_out
.
p_buffer
);
/* Date management */
p_pic
->
date
=
date_Get
(
&
p_sys
->
end_date
);
date_Increment
(
&
p_sys
->
end_date
,
1
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
return
p_pic
;
}
else
{
aout_buffer_t
*
p_aout_buffer
;
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
,
block_out
.
p_buffer
,
block_out
.
i_buffer
);
/* Date management */
p_aout_buffer
->
start_date
=
date_Get
(
&
p_sys
->
end_date
);
p_aout_buffer
->
end_date
=
date_Increment
(
&
p_sys
->
end_date
,
i_samples
);
p_out
->
vt
->
Release
(
(
IUnknown
*
)
p_out
);
return
p_aout_buffer
;
}
return
NULL
;
}
static
void
CopyPicture
(
decoder_t
*
p_dec
,
picture_t
*
p_pic
,
uint8_t
*
p_in
)
{
int
i_plane
,
i_line
,
i_width
,
i_dst_stride
;
uint8_t
*
p_dst
,
*
p_src
=
p_in
;
p_dst
=
p_pic
->
p
[
1
].
p_pixels
;
p_pic
->
p
[
1
].
p_pixels
=
p_pic
->
p
[
2
].
p_pixels
;
p_pic
->
p
[
2
].
p_pixels
=
p_dst
;
for
(
i_plane
=
0
;
i_plane
<
p_pic
->
i_planes
;
i_plane
++
)
{
p_dst
=
p_pic
->
p
[
i_plane
].
p_pixels
;
i_width
=
p_pic
->
p
[
i_plane
].
i_visible_pitch
;
i_dst_stride
=
p_pic
->
p
[
i_plane
].
i_pitch
;
for
(
i_line
=
0
;
i_line
<
p_pic
->
p
[
i_plane
].
i_lines
;
i_line
++
)
{
p_dec
->
p_vlc
->
pf_memcpy
(
p_dst
,
p_src
,
i_width
);
p_src
+=
i_width
;
p_dst
+=
i_dst_stride
;
}
}
p_dst
=
p_pic
->
p
[
1
].
p_pixels
;
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
/*****************************************************************************
/*****************************************************************************
* dmo.h : DirectMedia Object codec module for vlc
* dmo.h : DirectMedia Object codec module for vlc
*****************************************************************************
*****************************************************************************
* Copyright (C) 2002, 2003 VideoLAN
* Copyright (C) 2002, 2003 VideoLAN
* $Id$
* $Id$
*
*
* Author: Gildas Bazin <gbazin@videolan.org>
* Author: Gildas Bazin <gbazin@videolan.org>
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
*****************************************************************************/
static
const
GUID
IID_IUnknown
=
{
0x00000000
,
0x0000
,
0x0000
,
{
0xc0
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x46
}};
static
const
GUID
IID_IUnknown
=
{
0x00000000
,
0x0000
,
0x0000
,
{
0xc0
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x46
}};
static
const
GUID
IID_IClassFactory
=
{
0x00000001
,
0x0000
,
0x0000
,
{
0xc0
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x46
}};
static
const
GUID
IID_IClassFactory
=
{
0x00000001
,
0x0000
,
0x0000
,
{
0xc0
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x46
}};
static
const
GUID
IID_IMediaObject
=
{
0xd8ad0f58
,
0x5494
,
0x4102
,
{
0x97
,
0xc5
,
0xec
,
0x79
,
0x8e
,
0x59
,
0xbc
,
0xf4
}};
static
const
GUID
IID_IMediaObject
=
{
0xd8ad0f58
,
0x5494
,
0x4102
,
{
0x97
,
0xc5
,
0xec
,
0x79
,
0x8e
,
0x59
,
0xbc
,
0xf4
}};
static
const
GUID
IID_IMediaBuffer
=
{
0x59eff8b9
,
0x938c
,
0x4a26
,
{
0x82
,
0xf2
,
0x95
,
0xcb
,
0x84
,
0xcd
,
0xc8
,
0x37
}};
static
const
GUID
IID_IMediaBuffer
=
{
0x59eff8b9
,
0x938c
,
0x4a26
,
{
0x82
,
0xf2
,
0x95
,
0xcb
,
0x84
,
0xcd
,
0xc8
,
0x37
}};
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
}};
#define IUnknown IUnknownHack
static
const
GUID
MEDIASUBTYPE_RGB565
=
{
0xe436eb7b
,
0x524f
,
0x11ce
,
{
0x9f
,
0x53
,
0x00
,
0x20
,
0xaf
,
0x0b
,
0xa7
,
0x70
}};
#define IClassFactory IClassFactoryHack
typedef
struct
_IUnknown
IUnknown
;
#define IUnknown IUnknownHack
typedef
struct
_IClassFactory
IClassFactory
;
#define IClassFactory IClassFactoryHack
typedef
struct
_IEnumDMO
IEnumDMO
;
typedef
struct
_IUnknown
IUnknown
;
typedef
struct
_IMediaBuffer
IMediaBuffer
;
typedef
struct
_IClassFactory
IClassFactory
;
typedef
struct
_IMediaObject
IMediaObject
;
typedef
struct
_IEnumDMO
IEnumDMO
;
typedef
struct
_IMediaBuffer
IMediaBuffer
;
#ifndef STDCALL
typedef
struct
_IMediaObject
IMediaObject
;
#define STDCALL __stdcall
#endif
#ifndef STDCALL
#define STDCALL __stdcall
#define DMO_INPUT_DATA_BUFFER_SYNCPOINT 1
#endif
#define DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER 1
#define DMO_E_NOTACCEPTING 0x80040204
#define DMO_INPUT_DATA_BUFFER_SYNCPOINT 1
#define DMO_INPUT_DATA_BUFFERF_TIME 2
/*
#define DMO_INPUT_DATA_BUFFERF_TIMELENGTH 4
* DMO types definition
#define DMO_OUTPUT_DATA_BUFFER_SYNCPOINT 1
*/
#define DMO_OUTPUT_DATA_BUFFERF_TIME 2
typedef
struct
#define DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH 4
#ifdef HAVE_ATTRIBUTE_PACKED
#define DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER 1
__attribute__
((
__packed__
))
#define DMO_E_NOTACCEPTING 0x80040204
#endif
_DMO_PARTIAL_MEDIATYPE
/*
{
* DMO types definition
GUID
type
;
*/
GUID
subtype
;
typedef
struct
#ifdef HAVE_ATTRIBUTE_PACKED
}
DMO_PARTIAL_MEDIATYPE
;
__attribute__
((
__packed__
))
#endif
typedef
struct
_DMO_PARTIAL_MEDIATYPE
#ifdef HAVE_ATTRIBUTE_PACKED
{
__attribute__
((
__packed__
))
GUID
type
;
#endif
GUID
subtype
;
_DMO_OUTPUT_DATA_BUFFER
{
}
DMO_PARTIAL_MEDIATYPE
;
IMediaBuffer
*
pBuffer
;
uint32_t
dwStatus
;
typedef
struct
REFERENCE_TIME
rtTimestamp
;
#ifdef HAVE_ATTRIBUTE_PACKED
REFERENCE_TIME
rtTimelength
;
__attribute__
((
__packed__
))
#endif
}
DMO_OUTPUT_DATA_BUFFER
;
_DMO_OUTPUT_DATA_BUFFER
{
typedef
struct
IMediaBuffer
*
pBuffer
;
#ifdef HAVE_ATTRIBUTE_PACKED
uint32_t
dwStatus
;
__attribute__
((
__packed__
))
REFERENCE_TIME
rtTimestamp
;
#endif
REFERENCE_TIME
rtTimelength
;
_DMOMediaType
{
}
DMO_OUTPUT_DATA_BUFFER
;
GUID
majortype
;
GUID
subtype
;
typedef
struct
int
bFixedSizeSamples
;
#ifdef HAVE_ATTRIBUTE_PACKED
int
bTemporalCompression
;
__attribute__
((
__packed__
))
uint32_t
lSampleSize
;
#endif
GUID
formattype
;
_DMOMediaType
IUnknown
*
pUnk
;
{
uint32_t
cbFormat
;
GUID
majortype
;
char
*
pbFormat
;
GUID
subtype
;
int
bFixedSizeSamples
;
}
DMO_MEDIA_TYPE
;
int
bTemporalCompression
;
uint32_t
lSampleSize
;
/*
GUID
formattype
;
* IUnknown interface
IUnknown
*
pUnk
;
*/
uint32_t
cbFormat
;
typedef
struct
IUnknown_vt
char
*
pbFormat
;
{
/* IUnknown methods */
}
DMO_MEDIA_TYPE
;
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
void
**
ppvObject
);
/*
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
* IUnknown interface
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
*/
typedef
struct
IUnknown_vt
}
IUnknown_vt
;
{
struct
_IUnknown
{
IUnknown_vt
*
vt
;
};
/* IUnknown methods */
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
/*
void
**
ppvObject
);
* IClassFactory interface
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
*/
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
typedef
struct
IClassFactory_vt
{
}
IUnknown_vt
;
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
struct
_IUnknown
{
IUnknown_vt
*
vt
;
};
void
**
ppvObject
);
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
)
;
/*
long
(
STDCALL
*
Release
)(
IUnknown
*
This
)
;
* IClassFactory interface
long
(
STDCALL
*
CreateInstance
)(
IClassFactory
*
This
,
IUnknown
*
pUnkOuter
,
*/
const
GUID
*
riid
,
void
**
ppvObject
);
typedef
struct
IClassFactory_vt
}
IClassFactory_vt
;
{
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
struct
_IClassFactory
{
IClassFactory_vt
*
vt
;
};
void
**
ppvObject
);
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
)
;
/*
long
(
STDCALL
*
Release
)(
IUnknown
*
This
)
;
* IEnumDMO interface
long
(
STDCALL
*
CreateInstance
)(
IClassFactory
*
This
,
IUnknown
*
pUnkOuter
,
*/
const
GUID
*
riid
,
void
**
ppvObject
);
typedef
struct
IEnumDMO_vt
}
IClassFactory_vt
;
{
/* IUnknown methods */
struct
_IClassFactory
{
IClassFactory_vt
*
vt
;
};
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
void
**
ppvObject
);
/*
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
* IEnumDMO interface
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
*/
typedef
struct
IEnumDMO_vt
/* IEnumDMO methods */
{
long
(
STDCALL
*
Next
)(
IEnumDMO
*
This
,
uint32_t
cItemsToFetch
,
/* IUnknown methods */
const
GUID
*
pCLSID
,
WCHAR
**
Names
,
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
uint32_t
*
pcItemsFetched
);
void
**
ppvObject
);
long
(
STDCALL
*
Skip
)(
IEnumDMO
*
This
,
uint32_t
cItemsToSkip
);
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
long
(
STDCALL
*
Reset
)(
IEnumDMO
*
This
);
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
long
(
STDCALL
*
Clone
)(
IEnumDMO
*
This
,
IEnumDMO
**
ppEnum
);
/* IEnumDMO methods */
}
IEnumDMO_vt
;
long
(
STDCALL
*
Next
)(
IEnumDMO
*
This
,
uint32_t
cItemsToFetch
,
struct
_IEnumDMO
{
IEnumDMO_vt
*
vt
;
};
const
GUID
*
pCLSID
,
WCHAR
**
Names
,
uint32_t
*
pcItemsFetched
);
/*
long
(
STDCALL
*
Skip
)(
IEnumDMO
*
This
,
uint32_t
cItemsToSkip
);
* IMediaBuffer interface
long
(
STDCALL
*
Reset
)(
IEnumDMO
*
This
);
*/
long
(
STDCALL
*
Clone
)(
IEnumDMO
*
This
,
IEnumDMO
**
ppEnum
);
typedef
struct
IMediaBuffer_vt
{
}
IEnumDMO_vt
;
/* IUnknown methods */
struct
_IEnumDMO
{
IEnumDMO_vt
*
vt
;
};
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
void
**
ppvObject
);
/*
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
* IMediaBuffer interface
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
*/
typedef
struct
IMediaBuffer_vt
long
(
STDCALL
*
SetLength
)(
IMediaBuffer
*
This
,
uint32_t
cbLength
);
{
long
(
STDCALL
*
GetMaxLength
)(
IMediaBuffer
*
This
,
uint32_t
*
pcbMaxLength
);
/* IUnknown methods */
long
(
STDCALL
*
GetBufferAndLength
)(
IMediaBuffer
*
This
,
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
char
**
ppBuffer
,
uint32_t
*
pcbLength
);
void
**
ppvObject
);
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
}
IMediaBuffer_vt
;
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
struct
_IMediaBuffer
{
IMediaBuffer_vt
*
vt
;
};
long
(
STDCALL
*
SetLength
)(
IMediaBuffer
*
This
,
uint32_t
cbLength
);
/*
long
(
STDCALL
*
GetMaxLength
)(
IMediaBuffer
*
This
,
uint32_t
*
pcbMaxLength
);
* IMediaObject interface
long
(
STDCALL
*
GetBufferAndLength
)(
IMediaBuffer
*
This
,
*/
char
**
ppBuffer
,
uint32_t
*
pcbLength
);
typedef
struct
IMediaObject_vt
{
}
IMediaBuffer_vt
;
/* IUnknown methods */
struct
_IMediaBuffer
{
IMediaBuffer_vt
*
vt
;
};
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
void
**
ppvObject
);
/*
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
* IMediaObject interface
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
*/
typedef
struct
IMediaObject_vt
/* IEnumDMO methods */
{
long
(
STDCALL
*
GetStreamCount
)(
IMediaObject
*
This
,
/* IUnknown methods */
uint32_t
*
pcInputStreams
,
long
(
STDCALL
*
QueryInterface
)(
IUnknown
*
This
,
const
GUID
*
riid
,
uint32_t
*
pcOutputStreams
);
void
**
ppvObject
);
long
(
STDCALL
*
GetInputStreamInfo
)(
IMediaObject
*
This
,
long
(
STDCALL
*
AddRef
)(
IUnknown
*
This
);
uint32_t
dwInputStreamIndex
,
long
(
STDCALL
*
Release
)(
IUnknown
*
This
);
uint32_t
*
pdwFlags
);
long
(
STDCALL
*
GetOutputStreamInfo
)(
IMediaObject
*
This
,
/* IEnumDMO methods */
uint32_t
dwOutputStreamIndex
,
long
(
STDCALL
*
GetStreamCount
)(
IMediaObject
*
This
,
uint32_t
*
pdwFlags
);
uint32_t
*
pcInputStreams
,
long
(
STDCALL
*
GetInputType
)(
IMediaObject
*
This
,
uint32_t
*
pcOutputStreams
);
uint32_t
dwInputStreamIndex
,
long
(
STDCALL
*
GetInputStreamInfo
)(
IMediaObject
*
This
,
uint32_t
dwTypeIndex
,
uint32_t
dwInputStreamIndex
,
DMO_MEDIA_TYPE
*
pmt
);
uint32_t
*
pdwFlags
);
long
(
STDCALL
*
GetOutputType
)(
IMediaObject
*
This
,
long
(
STDCALL
*
GetOutputStreamInfo
)(
IMediaObject
*
This
,
uint32_t
dwOutputStreamIndex
,
uint32_t
dwOutputStreamIndex
,
uint32_t
dwTypeIndex
,
uint32_t
*
pdwFlags
);
DMO_MEDIA_TYPE
*
pmt
);
long
(
STDCALL
*
GetInputType
)(
IMediaObject
*
This
,
long
(
STDCALL
*
SetInputType
)(
IMediaObject
*
This
,
uint32_t
dwInputStreamIndex
,
uint32_t
dwInputStreamIndex
,
uint32_t
dwTypeIndex
,
const
DMO_MEDIA_TYPE
*
pmt
,
DMO_MEDIA_TYPE
*
pmt
);
uint32_t
dwFlags
);
long
(
STDCALL
*
GetOutputType
)(
IMediaObject
*
This
,
long
(
STDCALL
*
SetOutputType
)(
IMediaObject
*
This
,
uint32_t
dwOutputStreamIndex
,
uint32_t
dwOutputStreamIndex
,
uint32_t
dwTypeIndex
,
const
DMO_MEDIA_TYPE
*
pmt
,
DMO_MEDIA_TYPE
*
pmt
);
uint32_t
dwFlags
);
long
(
STDCALL
*
SetInputType
)(
IMediaObject
*
This
,
long
(
STDCALL
*
GetInputCurrentType
)(
IMediaObject
*
This
,
uint32_t
dwInputStreamIndex
,
uint32_t
dwInputStreamIndex
,
const
DMO_MEDIA_TYPE
*
pmt
,
DMO_MEDIA_TYPE
*
pmt
);
uint32_t
dwFlags
);
long
(
STDCALL
*
GetOutputCurrentType
)(
IMediaObject
*
This
,
long
(
STDCALL
*
SetOutputType
)(
IMediaObject
*
This
,
uint32_t
dwOutputStreamIndex
,
uint32_t
dwOutputStreamIndex
,
DMO_MEDIA_TYPE
*
pmt
);
const
DMO_MEDIA_TYPE
*
pmt
,
long
(
STDCALL
*
GetInputSizeInfo
)(
IMediaObject
*
This
,
uint32_t
dwFlags
);
uint32_t
dwInputStreamIndex
,
long
(
STDCALL
*
GetInputCurrentType
)(
IMediaObject
*
This
,
uint32_t
*
pcbSize
,
uint32_t
dwInputStreamIndex
,
uint32_t
*
pcbMaxLookahead
,
DMO_MEDIA_TYPE
*
pmt
);
uint32_t
*
pcbAlignment
);
long
(
STDCALL
*
GetOutputCurrentType
)(
IMediaObject
*
This
,
long
(
STDCALL
*
GetOutputSizeInfo
)(
IMediaObject
*
This
,
uint32_t
dwOutputStreamIndex
,
uint32_t
dwOutputStreamIndex
,
DMO_MEDIA_TYPE
*
pmt
);
uint32_t
*
pcbSize
,
long
(
STDCALL
*
GetInputSizeInfo
)(
IMediaObject
*
This
,
uint32_t
*
pcbAlignment
);
uint32_t
dwInputStreamIndex
,
long
(
STDCALL
*
GetInputMaxLatency
)(
IMediaObject
*
This
,
uint32_t
*
pcbSize
,
uint32_t
dwInputStreamIndex
,
uint32_t
*
pcbMaxLookahead
,
REFERENCE_TIME
*
prtMaxLatency
);
uint32_t
*
pcbAlignment
);
long
(
STDCALL
*
SetInputMaxLatency
)(
IMediaObject
*
This
,
long
(
STDCALL
*
GetOutputSizeInfo
)(
IMediaObject
*
This
,
uint32_t
dwInputStreamIndex
,
uint32_t
dwOutputStreamIndex
,
REFERENCE_TIME
rtMaxLatency
);
uint32_t
*
pcbSize
,
long
(
STDCALL
*
Flush
)(
IMediaObject
*
This
);
uint32_t
*
pcbAlignment
);
long
(
STDCALL
*
Discontinuity
)(
IMediaObject
*
This
,
long
(
STDCALL
*
GetInputMaxLatency
)(
IMediaObject
*
This
,
uint32_t
dwInputStreamIndex
);
uint32_t
dwInputStreamIndex
,
long
(
STDCALL
*
AllocateStreamingResources
)(
IMediaObject
*
This
);
REFERENCE_TIME
*
prtMaxLatency
);
long
(
STDCALL
*
FreeStreamingResources
)(
IMediaObject
*
This
);
long
(
STDCALL
*
SetInputMaxLatency
)(
IMediaObject
*
This
,
long
(
STDCALL
*
GetInputStatus
)(
IMediaObject
*
This
,
uint32_t
dwInputStreamIndex
,
uint32_t
dwInputStreamIndex
,
REFERENCE_TIME
rtMaxLatency
);
uint32_t
*
dwFlags
);
long
(
STDCALL
*
Flush
)(
IMediaObject
*
This
);
long
(
STDCALL
*
ProcessInput
)(
IMediaObject
*
This
,
long
(
STDCALL
*
Discontinuity
)(
IMediaObject
*
This
,
uint32_t
dwInputStreamIndex
,
uint32_t
dwInputStreamIndex
);
IMediaBuffer
*
pBuffer
,
long
(
STDCALL
*
AllocateStreamingResources
)(
IMediaObject
*
This
);
uint32_t
dwFlags
,
long
(
STDCALL
*
FreeStreamingResources
)(
IMediaObject
*
This
);
REFERENCE_TIME
rtTimestamp
,
long
(
STDCALL
*
GetInputStatus
)(
IMediaObject
*
This
,
REFERENCE_TIME
rtTimelength
);
uint32_t
dwInputStreamIndex
,
long
(
STDCALL
*
ProcessOutput
)(
IMediaObject
*
This
,
uint32_t
*
dwFlags
);
uint32_t
dwFlags
,
long
(
STDCALL
*
ProcessInput
)(
IMediaObject
*
This
,
uint32_t
cOutputBufferCount
,
uint32_t
dwInputStreamIndex
,
DMO_OUTPUT_DATA_BUFFER
*
pOutputBuffers
,
IMediaBuffer
*
pBuffer
,
uint32_t
*
pdwStatus
);
uint32_t
dwFlags
,
long
(
STDCALL
*
Lock
)(
IMediaObject
*
This
,
long
bLock
);
REFERENCE_TIME
rtTimestamp
,
REFERENCE_TIME
rtTimelength
);
}
IMediaObject_vt
;
long
(
STDCALL
*
ProcessOutput
)(
IMediaObject
*
This
,
struct
_IMediaObject
{
IMediaObject_vt
*
vt
;
};
uint32_t
dwFlags
,
uint32_t
cOutputBufferCount
,
/* Implementation of IMediaBuffer */
DMO_OUTPUT_DATA_BUFFER
*
pOutputBuffers
,
typedef
struct
_CMediaBuffer
uint32_t
*
pdwStatus
);
{
long
(
STDCALL
*
Lock
)(
IMediaObject
*
This
,
long
bLock
);
IMediaBuffer_vt
*
vt
;
int
i_ref
;
}
IMediaObject_vt
;
block_t
*
p_block
;
struct
_IMediaObject
{
IMediaObject_vt
*
vt
;
};
int
i_max_size
;
vlc_bool_t
b_own
;
/* Implementation of IMediaBuffer */
typedef
struct
_CMediaBuffer
}
CMediaBuffer
;
{
IMediaBuffer_vt
*
vt
;
CMediaBuffer
*
CMediaBufferCreate
(
block_t
*
,
int
,
vlc_bool_t
);
int
i_ref
;
block_t
*
p_block
;
int
i_max_size
;
vlc_bool_t
b_own
;
}
CMediaBuffer
;
CMediaBuffer
*
CMediaBufferCreate
(
block_t
*
,
int
,
vlc_bool_t
);
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