⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmo.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
        DMO_MEDIA_TYPE mt;        int i_chroma = VLC_FOURCC('Y','U','Y','2'), i_planes = 1, i_bpp = 16;        int i = 0;        /* Find out which chroma to use */        while( !p_dmo->vt->GetOutputType( p_dmo, 0, i++, &mt ) )        {            if( mt.subtype.Data1 == VLC_FOURCC('Y','V','1','2') )            {                i_chroma = mt.subtype.Data1;                i_planes = 3; i_bpp = 12;            }            DMOFreeMediaType( &mt );        }        p_dec->fmt_out.i_codec = i_chroma == VLC_FOURCC('Y','V','1','2') ?            VLC_FOURCC('I','4','2','0') : i_chroma;        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_dec->fmt_out.video.i_bits_per_pixel = i_bpp;        p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *            p_dec->fmt_out.video.i_width / p_dec->fmt_out.video.i_height;        p_bih = &p_vih->bmiHeader;        p_bih->biCompression = i_chroma;        p_bih->biHeight *= -1;        p_bih->biBitCount = p_dec->fmt_out.video.i_bits_per_pixel;        p_bih->biSizeImage = p_dec->fmt_in.video.i_width *            p_dec->fmt_in.video.i_height *            (p_dec->fmt_in.video.i_bits_per_pixel + 7) / 8;        p_bih->biPlanes = i_planes;        p_bih->biSize = sizeof(BITMAPINFOHEADER);        dmo_output_type.majortype = MEDIATYPE_Video;        dmo_output_type.formattype = FORMAT_VideoInfo;        dmo_output_type.subtype = dmo_output_type.majortype;        dmo_output_type.subtype.Data1 = p_bih->biCompression;        dmo_output_type.bFixedSizeSamples = VLC_TRUE;        dmo_output_type.bTemporalCompression = 0;        dmo_output_type.lSampleSize = p_bih->biSizeImage;        dmo_output_type.cbFormat = sizeof(VIDEOINFOHEADER);        dmo_output_type.pbFormat = (char *)p_vih;    }#ifdef DMO_DEBUG    /* Enumerate output types */    if( p_dec->fmt_in.i_cat == VIDEO_ES )    {        int i = 0;        DMO_MEDIA_TYPE mt;        while( !p_dmo->vt->GetOutputType( p_dmo, 0, i++, &mt ) )        {            msg_Dbg( p_dec, "available output chroma: %4.4s",                     (char *)&mt.subtype.Data1 );            DMOFreeMediaType( &mt );        }    }#endif    if( p_dmo->vt->SetOutputType( p_dmo, 0, &dmo_output_type, 0 ) )    {        msg_Err( p_dec, "can't set DMO output type" );        goto error;    }    msg_Dbg( p_dec, "DMO output type set" );    /* Allocate the memory needed to store the decoder's structure */    if( ( p_dec->p_sys = p_sys =          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )    {        msg_Err( p_dec, "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 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_dec, "GetOutputSizeInfo() failed" );            goto error;        }        else        {            msg_Dbg( p_dec, "GetOutputSizeInfo(): bytes %i, align %i",                     i_size, i_align );            p_sys->i_min_output = i_size;            p_sys->p_buffer = malloc( i_size );            if( !p_sys->p_buffer ) goto error;        }    }    /* Set output properties */    p_dec->fmt_out.i_cat = p_dec->fmt_in.i_cat;    if( p_dec->fmt_out.i_cat == AUDIO_ES )        date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );    else        date_Init( &p_sys->end_date, 25 /* FIXME */, 1 );    if( p_vih ) free( p_vih );    if( p_wf ) free( p_wf );    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_vih ) free( p_vih );    if( p_wf )  free( p_wf );    if( p_sys ) free( p_sys );    return VLC_EGENERIC;}/***************************************************************************** * LoadDMO: Load the DMO object *****************************************************************************/static int LoadDMO( vlc_object_t *p_this, HINSTANCE *p_hmsdmo_dll,                    IMediaObject **pp_dmo, es_format_t *p_fmt,                    vlc_bool_t b_out ){    DMO_PARTIAL_MEDIATYPE dmo_partial_type;    int i_err;#ifndef LOADER    long (STDCALL *OurDMOEnum)( const GUID *, uint32_t, uint32_t,                               const DMO_PARTIAL_MEDIATYPE *,                               uint32_t, const DMO_PARTIAL_MEDIATYPE *,                               IEnumDMO ** );    IEnumDMO *p_enum_dmo = NULL;    WCHAR *psz_dmo_name;    GUID clsid_dmo;    uint32_t i_dummy;#endif    GETCLASS GetClass;    IClassFactory *cFactory = NULL;    IUnknown *cObject = NULL;    codec_dll *codecs_table = b_out ? encoders_table : decoders_table;    int i_codec;    /* Look for a DMO which can handle the requested codec */    if( p_fmt->i_cat == AUDIO_ES )    {        uint16_t i_tag;        dmo_partial_type.type = MEDIATYPE_Audio;        dmo_partial_type.subtype = dmo_partial_type.type;        dmo_partial_type.subtype.Data1 = p_fmt->i_codec;        fourcc_to_wf_tag( p_fmt->i_codec, &i_tag );        if( i_tag ) dmo_partial_type.subtype.Data1 = i_tag;    }    else    {        dmo_partial_type.type = MEDIATYPE_Video;        dmo_partial_type.subtype = dmo_partial_type.type;        dmo_partial_type.subtype.Data1 = p_fmt->i_codec;    }#ifndef LOADER    /* Load msdmo DLL */    *p_hmsdmo_dll = LoadLibrary( "msdmo.dll" );    if( *p_hmsdmo_dll == NULL )    {        msg_Dbg( p_this, "failed loading msdmo.dll" );        return VLC_EGENERIC;    }    OurDMOEnum = (void *)GetProcAddress( *p_hmsdmo_dll, "DMOEnum" );    if( OurDMOEnum == NULL )    {        msg_Dbg( p_this, "GetProcAddress failed to find DMOEnum()" );        FreeLibrary( *p_hmsdmo_dll );        return VLC_EGENERIC;    }    if( !b_out )    {        i_err = OurDMOEnum( &GUID_NULL, 1 /*DMO_ENUMF_INCLUDE_KEYED*/,                            1, &dmo_partial_type, 0, NULL, &p_enum_dmo );    }    else    {        i_err = OurDMOEnum( &GUID_NULL, 1 /*DMO_ENUMF_INCLUDE_KEYED*/,                            0, NULL, 1, &dmo_partial_type, &p_enum_dmo );    }    if( i_err )    {        FreeLibrary( *p_hmsdmo_dll );        /* return VLC_EGENERIC; */        /* Try loading the dll directly */        goto loader;    }    /* Pickup the first available codec */    *pp_dmo = 0;    while( ( S_OK == p_enum_dmo->vt->Next( p_enum_dmo, 1, &clsid_dmo,                     &psz_dmo_name, &i_dummy /* NULL doesn't work */ ) ) )    {        char psz_temp[MAX_PATH];        wcstombs( psz_temp, psz_dmo_name, MAX_PATH );        msg_Dbg( p_this, "found DMO: %s", psz_temp );        CoTaskMemFree( psz_dmo_name );        /* Create DMO */        if( CoCreateInstance( &clsid_dmo, NULL, CLSCTX_INPROC,                              &IID_IMediaObject, (void **)pp_dmo ) )        {            msg_Warn( p_this, "can't create DMO: %s", psz_temp );            *pp_dmo = 0;        }        else break;    }    p_enum_dmo->vt->Release( (IUnknown *)p_enum_dmo );    if( !*pp_dmo )    {        FreeLibrary( *p_hmsdmo_dll );        /* return VLC_EGENERIC; */        /* Try loading the dll directly */        goto loader;    }    return VLC_SUCCESS;#endif   /* LOADER */ loader:    for( i_codec = 0; codecs_table[i_codec].i_fourcc != 0; i_codec++ )    {        if( codecs_table[i_codec].i_fourcc == p_fmt->i_codec )            break;    }    if( codecs_table[i_codec].i_fourcc == 0 )        return VLC_EGENERIC;    /* Can't happen */    *p_hmsdmo_dll = LoadLibrary( codecs_table[i_codec].psz_dll );    if( *p_hmsdmo_dll == NULL )    {        msg_Dbg( p_this, "failed loading '%s'",                 codecs_table[i_codec].psz_dll );        return VLC_EGENERIC;    }    GetClass = (GETCLASS)GetProcAddress( *p_hmsdmo_dll, "DllGetClassObject" );    if (!GetClass)    {        msg_Dbg( p_this, "GetProcAddress failed to find DllGetClassObject()" );        FreeLibrary( *p_hmsdmo_dll );        return VLC_EGENERIC;    }    i_err = GetClass( codecs_table[i_codec].p_guid, &IID_IClassFactory,                      (void**)&cFactory );    if( i_err || cFactory == NULL )    {        msg_Dbg( p_this, "no such class object" );        FreeLibrary( *p_hmsdmo_dll );        return VLC_EGENERIC;    }    i_err = cFactory->vt->CreateInstance( cFactory, 0, &IID_IUnknown,                                          (void**)&cObject );    cFactory->vt->Release( (IUnknown*)cFactory );    if( i_err || !cObject )    {        msg_Dbg( p_this, "class factory failure" );        FreeLibrary( *p_hmsdmo_dll );        return VLC_EGENERIC;    }    i_err = cObject->vt->QueryInterface( cObject, &IID_IMediaObject,                                        (void**)pp_dmo );    cObject->vt->Release( (IUnknown*)cObject );    if( i_err || !*pp_dmo )    {        msg_Dbg( p_this, "QueryInterface failure" );        FreeLibrary( *p_hmsdmo_dll );        return VLC_EGENERIC;    }    return VLC_SUCCESS;}/***************************************************************************** * DecoderClose: close codec *****************************************************************************/void DecoderClose( vlc_object_t *p_this ){    decoder_t *p_dec = (decoder_t*)p_this;    decoder_sys_t *p_sys = p_dec->p_sys;    if( !p_sys ) return;    if( p_sys->p_dmo ) p_sys->p_dmo->vt->Release( (IUnknown *)p_sys->p_dmo );    FreeLibrary( p_sys->hmsdmo_dll );#ifdef LOADER#if 0    Restore_LDT_Keeper( p_sys->ldt_fs );#endif#else    /* Uninitialize OLE/COM */    CoUninitialize();#endif    if( p_sys->p_buffer ) free( p_sys->p_buffer );    free( p_sys );}/**************************************************************************** * DecodeBlock: the whole thing **************************************************************************** * This function must be fed with ogg packets. ****************************************************************************/static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    block_t *p_block;    int i_result;    DMO_OUTPUT_DATA_BUFFER db;    CMediaBuffer *p_out;    block_t block_out;    uint32_t i_status;    if( p_sys == NULL )    {        if( DecOpen( VLC_OBJECT(p_dec) ) )        {            msg_Err( p_dec, "DecOpen failed" );            return NULL;        }        p_sys = p_dec->p_sys;    }    if( !pp_block ) return NULL;    p_block = *pp_block;    /* Won't work with streams with B-frames, but do we have any ? */    if( p_block && p_block->i_pts <= 0 ) p_block->i_pts = p_block->i_dts;    /* Date management */    if( p_block && p_block->i_pts > 0 &&        p_block->i_pts != date_Get( &p_sys->end_date ) )    {        date_Set( &p_sys->end_date, p_block->i_pts );    }#if 0 /* Breaks the video decoding */    if( !date_Get( &p_sys->end_date ) )    {        /* We've just started the stream, wait for the first PTS. */        if( p_block ) block_Release( p_block );        return NULL;    }#endif    /* Feed input to the DMO */    if( p_block && p_block->i_buffer )    {        CMediaBuffer *p_in;        p_in = CMediaBufferCreate( p_block, p_block->i_buffer, VLC_TRUE );        i_result = p_sys->p_dmo->vt->ProcessInput( p_sys->p_dmo, 0,                       (IMediaBuffer *)p_in, DMO_INPUT_DATA_BUFFERF_SYNCPOINT,                       0, 0 );        p_in->vt->Release( (IUnknown *)p_in );        if( i_result == S_FALSE )        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -