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

📄 dmo.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
                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 */        int i_plane, i_line, i_width, i_src_stride;        picture_t *p_pic = (picture_t *)p_data;        uint8_t *p_dst;        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;        p_block_in = block_New( p_enc, i_buffer );        /* Copy picture stride by stride */        p_dst = p_block_in->p_buffer;        for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )        {            uint8_t *p_src = p_pic->p[i_plane].p_pixels;            i_width = p_pic->p[i_plane].i_visible_pitch;            i_src_stride = p_pic->p[i_plane].i_pitch;            for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines;                 i_line++ )            {                p_enc->p_vlc->pf_memcpy( p_dst, p_src, i_width );                p_dst += i_width;                p_src += i_src_stride;            }        }        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 );            block_Release( p_block_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 );            block_Release( p_block_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        }        if( p_enc->fmt_out.i_cat == VIDEO_ES )        {            if( db.dwStatus & DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT )                p_block_out->i_flags |= BLOCK_FLAG_TYPE_I;            else                p_block_out->i_flags |= BLOCK_FLAG_TYPE_P;        }        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;    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    free( p_sys );}

⌨️ 快捷键说明

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