]> git.sesse.net Git - vlc/commitdiff
* dmo: - fixed init of WAVEFORMATEX (cbSize is only the size of extra datas).
authorLaurent Aimar <fenrir@videolan.org>
Sun, 8 Aug 2004 01:39:23 +0000 (01:39 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Sun, 8 Aug 2004 01:39:23 +0000 (01:39 +0000)
        - force 16 bits output.
        - support for mplayer loader.
 I can't test under win32 so I hope it still compiles.

modules/codec/dmo/buffer.c
modules/codec/dmo/dmo.c
modules/codec/dmo/dmo.h

index 8cf3f8cada32bb4421e9533f5fa874ce990be5d7..71ef582a5a14c0dfe8a6c5ccf70fb07df0595a37 100644 (file)
 #include <vlc/decoder.h>
 #include <vlc/vout.h>
 
-#include <objbase.h>
+#define LOADER
+#ifdef LOADER
+#   include <wine/winerror.h>
+#   include <dmo/dmo.h>
+#   include <dmo/dmo_interfaces.h>
+#   include <dmo/dmo_guids.h>
+#   define _RECT32_
+#   define _GUID_DEFINED
+#   define _REFERENCE_TIME_
+#   define _VIDEOINFOHEADER_
+#else
+#   include <objbase.h>
+#endif
 #include "codecs.h"
 #include "dmo.h"
 
index 6a1dd047273dcffba4cbf0e4b0c6d0f77cfc2478..4c9a5dab6e3a9f3b5f377715f9626923f3155844 100644 (file)
 #include <vlc/decoder.h>\r
 #include <vlc/vout.h>\r
 \r
-#include <objbase.h>\r
-#include "codecs.h"\r
+#define LOADER\r
+#ifdef LOADER\r
+/* Need the w32dll loader from mplayer */\r
+#   include <wine/winerror.h>\r
+#   include <dmo/dmo.h>\r
+#   include <dmo/dmo_interfaces.h>\r
+#   include <dmo/dmo_guids.h>\r
+#   include <ldt_keeper.h>\r
+\r
+/* Avoid  codecs.h to redefine a few symbols */\r
+#   define _RECT32_\r
+#   define _GUID_DEFINED\r
+#   define _REFERENCE_TIME_\r
+#   define _VIDEOINFOHEADER_\r
+\r
+/* Ugly, wine loader and vlc doesn't use the same field name for GUID */\r
+#define Data1 f1\r
+#define Data2 f2\r
+#define Data3 f3\r
+#define Data4 f4\r
+\r
+/* Not Needed */\r
+HRESULT CoInitialize( LPVOID pvReserved ) { return (HRESULT)-1; }\r
+void CoUninitialize(void) { }\r
+\r
+/* */\r
+HMODULE   WINAPI LoadLibraryA(LPCSTR);\r
+FARPROC   WINAPI GetProcAddress(HMODULE,LPCSTR);\r
+int       WINAPI FreeLibrary(HMODULE);\r
+\r
+typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);\r
+\r
+#else\r
+#   include <objbase.h>\r
+#endif\r
+\r
 #include "dmo.h"\r
+#include "codecs.h"\r
 \r
 static int pi_channels_maps[7] =\r
 {\r
@@ -53,6 +88,7 @@ static int pi_channels_maps[7] =
 /*****************************************************************************\r
  * Module descriptor\r
  *****************************************************************************/\r
+static int  Open         ( vlc_object_t * );\r
 static int  DecoderOpen  ( vlc_object_t * );\r
 static void DecoderClose ( vlc_object_t * );\r
 static void *DecodeBlock ( decoder_t *, block_t ** );\r
@@ -63,7 +99,7 @@ vlc_module_begin();
     set_description( _("DirectMedia Object decoder") );\r
     add_shortcut( "dmo" );\r
     set_capability( "decoder", 1 );\r
-    set_callbacks( DecoderOpen, DecoderClose );\r
+    set_callbacks( Open, DecoderClose );\r
 vlc_module_end();\r
 \r
 /*****************************************************************************\r
@@ -82,8 +118,81 @@ struct decoder_sys_t
     uint8_t *p_buffer;\r
 \r
     audio_date_t end_date;\r
+\r
+#ifdef LOADER\r
+    ldt_fs_t    *ldt_fs;\r
+#endif\r
+};\r
+\r
+#ifdef LOADER\r
+static const GUID guid_wmv9 = { 0x724bb6a4, 0xe526, 0x450f, { 0xaf, 0xfa, 0xab, 0x9b, 0x45, 0x12, 0x91, 0x11 } };\r
+static const GUID guid_wma9 = { 0x27ca0808, 0x01f5, 0x4e7a, { 0x8b, 0x05, 0x87, 0xf8, 0x07, 0xa2, 0x33, 0xd1 } };\r
+\r
+static const GUID guid_wmv = { 0x82d353df, 0x90bd, 0x4382, { 0x8b, 0xc2, 0x3f, 0x61, 0x92, 0xb7, 0x6e, 0x34 } };\r
+static const GUID guid_wma = { 0x874131cb, 0x4ecc, 0x443b, { 0x89, 0x48, 0x74, 0x6b, 0x89, 0x59, 0x5d, 0x20 } };\r
+\r
+static const struct\r
+{\r
+    vlc_fourcc_t i_fourcc;\r
+    const char   *psz_dll;\r
+    const GUID   *p_guid;\r
+} codecs_table[] =\r
+{\r
+    /* WM3 */\r
+    { VLC_FOURCC('W','M','V','3'), "wmv9dmod.dll", &guid_wmv9 },\r
+    { VLC_FOURCC('w','m','v','3'), "wmv9dmod.dll", &guid_wmv9 },\r
+    /* WMV2 */\r
+    { VLC_FOURCC('W','M','V','2'), "wmvdmod.dll", &guid_wmv },\r
+    { VLC_FOURCC('w','m','v','2'), "wmvdmod.dll", &guid_wmv },\r
+    /* WMV1 */\r
+    { VLC_FOURCC('W','M','V','1'), "wmvdmod.dll", &guid_wmv },\r
+    { VLC_FOURCC('w','m','v','1'), "wmvdmod.dll", &guid_wmv },\r
+\r
+    /* WMA 3*/\r
+    { VLC_FOURCC('W','M','A','3'), "wma9dmod.dll", &guid_wma9 },\r
+    { VLC_FOURCC('w','m','a','3'), "wma9dmod.dll", &guid_wma9 },\r
+\r
+    /* */\r
+    { 0, NULL, NULL }\r
 };\r
 \r
+#endif\r
+\r
+/*****************************************************************************\r
+ * Open: open dmo codec\r
+ *****************************************************************************/\r
+static int Open( vlc_object_t *p_this )\r
+{\r
+#ifndef LOADER\r
+    return DecoderOpen( p_this );\r
+#else\r
+    decoder_t *p_dec = (decoder_t*)p_this;\r
+    int i;\r
+    /* We can't open it now, because of ldt_keeper or something\r
+     * Open/Decode/Close has to be done in the same thread */\r
+\r
+    p_dec->p_sys = NULL;\r
+\r
+\r
+    /* Probe if we support it */\r
+    for( i = 0; codecs_table[i].i_fourcc != 0; i++ )\r
+    {\r
+        if( codecs_table[i].i_fourcc == p_dec->fmt_in.i_codec )\r
+        {\r
+            msg_Dbg( p_dec, "DMO codec for %4.4s may work with dll=%s",\r
+                     (char*)&p_dec->fmt_in.i_codec,\r
+                     codecs_table[i].psz_dll );\r
+\r
+            /* Set callbacks */\r
+            p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))DecodeBlock;\r
+            p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))DecodeBlock;\r
+            return VLC_SUCCESS;\r
+        }\r
+    }\r
+    return VLC_EGENERIC;\r
+#endif\r
+}\r
+\r
 /*****************************************************************************\r
  * DecoderOpen: open dmo codec\r
  *****************************************************************************/\r
@@ -94,21 +203,47 @@ static int DecoderOpen( vlc_object_t *p_this )
 \r
     DMO_PARTIAL_MEDIATYPE dmo_partial_type;\r
     DMO_MEDIA_TYPE dmo_input_type, dmo_output_type;\r
-    IEnumDMO *p_enum_dmo = NULL; \r
     IMediaObject *p_dmo = NULL;\r
-    WCHAR *psz_dmo_name;\r
-    GUID clsid_dmo;\r
 \r
     VIDEOINFOHEADER *p_vih = NULL;\r
     WAVEFORMATEX *p_wf = NULL;\r
 \r
+#ifdef LOADER\r
+    ldt_fs_t *ldt_fs = Setup_LDT_Keeper();\r
+#endif /* LOADER */\r
+\r
+    HINSTANCE hmsdmo_dll = NULL;\r
+\r
+    /* Look for a DMO which can handle the requested codec */\r
+    if( p_dec->fmt_in.i_cat == AUDIO_ES )\r
+    {\r
+        uint16_t i_tag;\r
+        dmo_partial_type.type = MEDIATYPE_Audio;\r
+        dmo_partial_type.subtype = dmo_partial_type.type;\r
+        dmo_partial_type.subtype.Data1 = p_dec->fmt_in.i_codec;\r
+        fourcc_to_wf_tag( p_dec->fmt_in.i_codec, &i_tag );\r
+        if( i_tag ) dmo_partial_type.subtype.Data1 = i_tag;\r
+    }\r
+    else\r
+    {\r
+        dmo_partial_type.type = MEDIATYPE_Video;\r
+        dmo_partial_type.subtype = dmo_partial_type.type;\r
+        dmo_partial_type.subtype.Data1 = p_dec->fmt_in.i_codec;\r
+    }\r
+\r
+#ifndef LOADER\r
+  { /* <- ugly ? yes */\r
+    IEnumDMO *p_enum_dmo = NULL;\r
+    WCHAR *psz_dmo_name;\r
+    GUID clsid_dmo;\r
     HRESULT (STDCALL *OurDMOEnum)( const GUID *, uint32_t, uint32_t,\r
                            const DMO_PARTIAL_MEDIATYPE *,\r
                            uint32_t, const DMO_PARTIAL_MEDIATYPE *,\r
                            IEnumDMO ** );\r
 \r
+\r
     /* Load msdmo DLL */\r
-    HINSTANCE hmsdmo_dll = LoadLibrary( "msdmo.dll" );\r
+    hmsdmo_dll = LoadLibrary( "msdmo.dll" );\r
     if( hmsdmo_dll == NULL )\r
     {\r
         msg_Dbg( p_dec, "failed loading msdmo.dll" );\r
@@ -122,22 +257,6 @@ static int DecoderOpen( vlc_object_t *p_this )
         return VLC_EGENERIC;\r
     }\r
 \r
-    /* Look for a DMO which can handle the requested codec */\r
-    if( p_dec->fmt_in.i_cat == AUDIO_ES )\r
-    {\r
-        uint16_t i_tag;\r
-        dmo_partial_type.type = MEDIATYPE_Audio;\r
-        dmo_partial_type.subtype = dmo_partial_type.type;\r
-        dmo_partial_type.subtype.Data1 = p_dec->fmt_in.i_codec;\r
-        fourcc_to_wf_tag( p_dec->fmt_in.i_codec, &i_tag );\r
-        if( i_tag ) dmo_partial_type.subtype.Data1 = i_tag;\r
-    }\r
-    else\r
-    {\r
-        dmo_partial_type.type = MEDIATYPE_Video;\r
-        dmo_partial_type.subtype = dmo_partial_type.type;\r
-        dmo_partial_type.subtype.Data1 = p_dec->fmt_in.i_codec;\r
-    }\r
 \r
     /* Initialize OLE/COM */\r
     CoInitialize( 0 );\r
@@ -173,6 +292,76 @@ static int DecoderOpen( vlc_object_t *p_this )
         msg_Err( p_dec, "can't create DMO" );\r
         goto error;\r
     }\r
+  }\r
+#else   /* LOADER */\r
+  {\r
+    GETCLASS GetClass;\r
+    struct IClassFactory* cFactory = NULL;\r
+    struct IUnknown* cObject = NULL;\r
+\r
+    int i_err;\r
+    int i_codec;\r
+    for( i_codec = 0; codecs_table[i_codec].i_fourcc != 0; i_codec++ )\r
+    {\r
+        if( codecs_table[i_codec].i_fourcc == p_dec->fmt_in.i_codec )\r
+            break;\r
+    }\r
+    if( codecs_table[i_codec].i_fourcc == 0 )\r
+        return VLC_EGENERIC;    /* Can't happen */\r
+\r
+    hmsdmo_dll = LoadLibrary( codecs_table[i_codec].psz_dll );\r
+    if( hmsdmo_dll == NULL )\r
+    {\r
+        msg_Dbg( p_dec, "failed loading '%s'", codecs_table[i_codec].psz_dll );\r
+        return VLC_EGENERIC;\r
+    }\r
+\r
+    GetClass = (GETCLASS)GetProcAddress( hmsdmo_dll, "DllGetClassObject");\r
+    if (!GetClass)\r
+    {\r
+        msg_Dbg( p_dec, "GetProcAddress failed to find DllGetClassObject()" );\r
+        FreeLibrary( hmsdmo_dll );\r
+        return VLC_EGENERIC;\r
+    }\r
+\r
+    i_err = GetClass( codecs_table[i_codec].p_guid, &IID_IClassFactory, (void**)&cFactory );\r
+    if( i_err || cFactory == NULL )\r
+    {\r
+        msg_Dbg( p_dec, "no such class object" );\r
+        FreeLibrary( hmsdmo_dll );\r
+        return VLC_EGENERIC;\r
+    }\r
+\r
+    i_err = cFactory->vt->CreateInstance( cFactory, 0, &IID_IUnknown, (void**)&cObject );\r
+    cFactory->vt->Release((IUnknown*)cFactory );\r
+    if( i_err || !cObject )\r
+    {\r
+        msg_Dbg( p_dec, "class factory failure" );\r
+        FreeLibrary( hmsdmo_dll );\r
+        return VLC_EGENERIC;\r
+    }\r
+    i_err = cObject->vt->QueryInterface( cObject, &IID_IMediaObject, (void**)&p_dmo );\r
+#if 0\r
+    if (hr == 0)\r
+    {\r
+            /* query for some extra available interface */\r
+        HRESULT r = object->vt->QueryInterface(object, &IID_IMediaObjectInPlace, (void**)&This->m_pInPlace);\r
+            if (r == 0 && This->m_pInPlace)\r
+        printf("DMO dll supports InPlace - PLEASE REPORT to developer\n");\r
+        r = object->vt->QueryInterface(object, &IID_IDMOVideoOutputOptimizations, (void**)&This->m_pOptim);\r
+        if (r == 0 && This->m_pOptim)\r
+        {\r
+                unsigned long flags;\r
+        r = This->m_pOptim->vt->QueryOperationModePreferences(This->m_pOptim, 0, &flags);\r
+        printf("DMO dll supports VO Optimizations %ld %lx\n", r, flags);\r
+        if (flags & DMO_VOSF_NEEDS_PREVIOUS_SAMPLE)\r
+            printf("DMO dll might use previous sample when requested\n");\r
+        }\r
+    }\r
+#endif\r
+    cObject->vt->Release((IUnknown*)cObject );\r
+  }\r
+#endif  /* LOADER */\r
 \r
     /* Setup input format */\r
     memset( &dmo_input_type, 0, sizeof(dmo_input_type) );\r
@@ -195,7 +384,7 @@ static int DecoderOpen( vlc_object_t *p_this )
         p_wf->wBitsPerSample = p_dec->fmt_in.audio.i_bitspersample;\r
         p_wf->nBlockAlign = p_dec->fmt_in.audio.i_blockalign;\r
         p_wf->nAvgBytesPerSec = p_dec->fmt_in.i_bitrate / 8;\r
-        p_wf->cbSize = i_size;\r
+        p_wf->cbSize = p_dec->fmt_in.i_extra;\r
 \r
         dmo_input_type.formattype = FORMAT_WaveFormatEx;\r
         dmo_input_type.cbFormat   = i_size;\r
@@ -255,8 +444,7 @@ static int DecoderOpen( vlc_object_t *p_this )
         p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;\r
         p_dec->fmt_out.audio.i_rate     = p_dec->fmt_in.audio.i_rate;\r
         p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;\r
-        p_dec->fmt_out.audio.i_bitspersample =\r
-            p_dec->fmt_in.audio.i_bitspersample;\r
+        p_dec->fmt_out.audio.i_bitspersample = 16;//p_dec->fmt_in.audio.i_bitspersample; We request 16\r
         p_dec->fmt_out.audio.i_physical_channels =\r
             p_dec->fmt_out.audio.i_original_channels =\r
                 pi_channels_maps[p_dec->fmt_out.audio.i_channels];\r
@@ -269,7 +457,7 @@ static int DecoderOpen( vlc_object_t *p_this )
             p_wf->wBitsPerSample / 8 * p_wf->nChannels;\r
         p_wf->nAvgBytesPerSec =\r
             p_wf->nSamplesPerSec * p_wf->nBlockAlign;\r
-        p_wf->cbSize = sizeof(WAVEFORMATEX);\r
+        p_wf->cbSize = 0;\r
 \r
         dmo_output_type.formattype = FORMAT_WaveFormatEx;\r
         dmo_output_type.subtype    = MEDIASUBTYPE_PCM;\r
@@ -359,6 +547,9 @@ static int DecoderOpen( vlc_object_t *p_this )
 \r
     p_sys->hmsdmo_dll = hmsdmo_dll;\r
     p_sys->p_dmo = p_dmo;\r
+#ifdef LOADER\r
+    p_sys->ldt_fs = ldt_fs;\r
+#endif\r
 \r
     /* Find out some properties of the output */\r
     {\r
@@ -424,6 +615,12 @@ void DecoderClose( vlc_object_t *p_this )
 \r
     FreeLibrary( p_sys->hmsdmo_dll );\r
 \r
+#if 0\r
+#ifdef LOADER\r
+    Restore_LDT_Keeper( p_sys->ldt_fs );\r
+#endif\r
+#endif\r
+\r
     if( p_sys->p_buffer ) free( p_sys->p_buffer );\r
     free( p_sys );\r
 }\r
@@ -445,6 +642,16 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
     uint32_t i_status, i_buffer_out;\r
     uint8_t *p_buffer_out;\r
 \r
+    if( p_sys == NULL )\r
+    {\r
+        if( DecoderOpen( VLC_OBJECT(p_dec) ) )\r
+        {\r
+            msg_Err( p_dec, "DecoderOpen failed" );\r
+            return NULL;\r
+        }\r
+        p_sys = p_dec->p_sys;\r
+    }\r
+\r
     if( !pp_block ) return NULL;\r
 \r
     p_block = *pp_block;\r
@@ -580,8 +787,8 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
     {\r
         aout_buffer_t *p_aout_buffer;\r
         int i_samples = i_buffer_out /\r
-            ( p_dec->fmt_in.audio.i_bitspersample *\r
-              p_dec->fmt_in.audio.i_channels / 8 );\r
+            ( p_dec->fmt_out.audio.i_bitspersample *\r
+              p_dec->fmt_out.audio.i_channels / 8 );\r
 \r
         p_aout_buffer = p_dec->pf_aout_buffer_new( p_dec, i_samples );\r
         memcpy( p_aout_buffer->p_buffer, p_buffer_out, i_buffer_out );\r
index 35c5080df15539d1a566fe050e83324902ec3ddb..030c0b46052841aa2b3996c23d88756e2eb7afcc 100644 (file)
@@ -36,10 +36,7 @@ static const GUID MEDIASUBTYPE_YV12 = {0x32315659, 0x0000, 0x0010, {0x80, 0x00,
 #ifdef WIN32\r
 #   define IUnknown IUnknownHack\r
 #endif\r
-typedef struct _IUnknown IUnknown;\r
-typedef struct _IEnumDMO IEnumDMO;\r
-typedef struct _IMediaBuffer IMediaBuffer;\r
-typedef struct _IMediaObject IMediaObject;\r
+\r
 #ifndef STDCALL\r
 #define STDCALL __stdcall\r
 #endif\r
@@ -62,6 +59,25 @@ typedef struct
 \r
 } DMO_PARTIAL_MEDIATYPE;\r
 \r
+/* Implementation of IMediaBuffer */\r
+typedef struct _CMediaBuffer\r
+{\r
+    IMediaBuffer_vt *vt;\r
+    int i_ref;\r
+    block_t *p_block;\r
+    int i_max_size;\r
+    vlc_bool_t b_own;\r
+\r
+} CMediaBuffer;\r
+\r
+CMediaBuffer *CMediaBufferCreate( block_t *, int, vlc_bool_t );\r
+\r
+#ifndef LOADER\r
+typedef struct _IUnknown IUnknown;\r
+typedef struct _IEnumDMO IEnumDMO;\r
+typedef struct _IMediaBuffer IMediaBuffer;\r
+typedef struct _IMediaObject IMediaObject;\r
+\r
 typedef struct\r
 #ifdef HAVE_ATTRIBUTE_PACKED\r
     __attribute__((__packed__))\r
@@ -229,16 +245,5 @@ typedef struct IMediaObject_vt
 \r
 } IMediaObject_vt;\r
 struct _IMediaObject { IMediaObject_vt* vt; };\r
+#endif  /* !define LOADER */\r
 \r
-/* Implementation of IMediaBuffer */\r
-typedef struct _CMediaBuffer\r
-{\r
-    IMediaBuffer_vt *vt;\r
-    int i_ref;\r
-    block_t *p_block;\r
-    int i_max_size;\r
-    vlc_bool_t b_own;\r
-\r
-} CMediaBuffer;\r
-\r
-CMediaBuffer *CMediaBufferCreate( block_t *, int, vlc_bool_t );\r