Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
bb7f54bb
Commit
bb7f54bb
authored
Aug 17, 2004
by
Gildas Bazin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/codec/dmo/*: added dmo encoder (can't get video encoding to work though).
parent
2dfaaa53
Changes
2
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