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

📄 dmo.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
            /* No output generated */#ifdef DMO_DEBUG            msg_Dbg( p_dec, "ProcessInput(): no output generated" );#endif            return NULL;        }        else if( i_result == DMO_E_NOTACCEPTING )        {            /* Need to call ProcessOutput */            msg_Dbg( p_dec, "ProcessInput(): not accepting" );        }        else if( i_result != S_OK )        {            msg_Dbg( p_dec, "ProcessInput(): failed" );            return NULL;        }        else        {            //msg_Dbg( p_dec, "ProcessInput(): successful" );            *pp_block = 0;        }    }    else if( p_block && !p_block->i_buffer )    {        block_Release( p_block );        *pp_block = 0;    }    /* Get output from the DMO */    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 );    memset( &db, 0, sizeof(db) );    db.pBuffer = (IMediaBuffer *)p_out;    i_result = p_sys->p_dmo->vt->ProcessOutput( p_sys->p_dmo,                   DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER,                   1, &db, &i_status );    if( i_result != S_OK )    {        if( i_result != S_FALSE )            msg_Dbg( p_dec, "ProcessOutput(): failed" );#if DMO_DEBUG        else            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_visible_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;    vih.AvgTimePerFrame = I64C(10000000) / 25; //FIXME    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;    /* Get the private data for the codec */    while( 1 )    {        IWMCodecPrivateData *p_privdata;        VIDEOINFOHEADER *p_vih;        uint8_t *p_data = 0;        uint32_t i_data = 0, i_vih;        i_err = p_dmo->vt->QueryInterface( (IUnknown *)p_dmo,                                           &IID_IWMCodecPrivateData,                                           (void **)&p_privdata );        if( i_err ) break;        i_err = p_privdata->vt->SetPartialOutputType( p_privdata, &dmo_type );        if( i_err )        {            msg_Err( p_enc, "SetPartialOutputType() failed" );            p_privdata->vt->Release( (IUnknown *)p_privdata );            break;        }        i_err = p_privdata->vt->GetPrivateData( p_privdata, NULL, &i_data );        if( i_err )        {            msg_Err( p_enc, "GetPrivateData() failed" );            p_privdata->vt->Release( (IUnknown *)p_privdata );            break;        }        p_data = malloc( i_data );        i_err = p_privdata->vt->GetPrivateData( p_privdata, p_data, &i_data );        /* Update the media type with the private data */        i_vih = dmo_type.cbFormat + i_data;        p_vih = CoTaskMemAlloc( i_vih );        memcpy( p_vih, dmo_type.pbFormat, dmo_type.cbFormat );        memcpy( ((uint8_t *)p_vih) + dmo_type.cbFormat, p_data, i_data );        DMOFreeMediaType( &dmo_type );        dmo_type.pbFormat = p_vih;        dmo_type.cbFormat = i_vih;        msg_Dbg( p_enc, "found extra data: %i", i_data );        p_enc->fmt_out.i_extra = i_data;        p_enc->fmt_out.p_extra = p_data;        break;    }    i_err = p_dmo->vt->SetOutputType( p_dmo, 0, &dmo_type, 0 );    p_vih = (VIDEOINFOHEADER *)dmo_type.pbFormat;    p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','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.i_codec = AOUT_FMT_S16_NE;    p_enc->fmt_in.audio.i_bitspersample = 16;    /* 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 <

⌨️ 快捷键说明

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