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

📄 dshow.cpp

📁 video linux conference
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    mt[mt_count++] = *p_mt;                    /* Setup a few properties like the audio latency */                    IAMBufferNegotiation *p_ambuf;                    if( SUCCEEDED( p_output_pin->QueryInterface(                          IID_IAMBufferNegotiation, (void **)&p_ambuf ) ) )                    {                        ALLOCATOR_PROPERTIES AllocProp;                        AllocProp.cbAlign = -1;                        /* 100 ms of latency */                        AllocProp.cbBuffer = i_current_channels *                          i_current_samplespersec *                          i_current_bitspersample / 8 / 10;                        AllocProp.cbPrefix = -1;                        AllocProp.cBuffers = -1;                        p_ambuf->SuggestAllocatorProperties( &AllocProp );                        p_ambuf->Release();                    }                }                else FreeMediaType( *p_mt );            }            else if( i_current_fourcc && p_mt->majortype == MEDIATYPE_Stream )            {                msg_Dbg( p_this, "EnumDeviceCaps: input pin "                         "accepts stream format: %4.4s",                         (char *)&i_current_fourcc );                if( ( !i_fourcc || i_fourcc == i_current_fourcc ) &&                    mt_count < mt_max )                {                    /* Pick match */                    mt[mt_count++] = *p_mt;                    i_fourcc = i_current_fourcc;                }                else FreeMediaType( *p_mt );            }            else            {                char *psz_type = "unknown";                if( p_mt->majortype == MEDIATYPE_Video ) psz_type = "video";                if( p_mt->majortype == MEDIATYPE_Audio ) psz_type = "audio";                if( p_mt->majortype == MEDIATYPE_Stream ) psz_type = "stream";                msg_Dbg( p_this, "EnumDeviceCaps: input pin media: unknown format "                         "(%s %4.4s)", psz_type, (char *)&p_mt->subtype );                FreeMediaType( *p_mt );            }            CoTaskMemFree( (PVOID)p_mt );        }        p_enummt->Release();        p_output_pin->Release();    }    p_enumpins->Release();    return mt_count;}/***************************************************************************** * ReadCompressed: reads compressed (MPEG/DV) data from the device. ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, otherwise the number of * bytes. *****************************************************************************/static block_t *ReadCompressed( access_t *p_access ){    access_sys_t   *p_sys = p_access->p_sys;    dshow_stream_t *p_stream = NULL;    VLCMediaSample sample;    /* Read 1 DV/MPEG frame (they contain the video and audio data) */    /* There must be only 1 elementary stream to produce a valid stream     * of MPEG or DV data */    p_stream = p_sys->pp_streams[0];    while( 1 )    {        if( p_access->b_die || p_access->b_error ) return 0;        /* Get new sample/frame from the elementary stream (blocking). */        vlc_mutex_lock( &p_sys->lock );        if( p_stream->p_capture_filter->CustomGetPin()              ->CustomGetSample( &sample ) != S_OK )        {            /* No data available. Wait until some data has arrived */            vlc_cond_wait( &p_sys->wait, &p_sys->lock );            vlc_mutex_unlock( &p_sys->lock );            continue;        }        vlc_mutex_unlock( &p_sys->lock );        /*         * We got our sample         */        block_t *p_block;        uint8_t *p_data;        int i_data_size = sample.p_sample->GetActualDataLength();        if( !i_data_size || !(p_block = block_New( p_access, i_data_size )) )        {            sample.p_sample->Release();            continue;        }        sample.p_sample->GetPointer( &p_data );        p_access->p_vlc->pf_memcpy( p_block->p_buffer, p_data, i_data_size );        sample.p_sample->Release();        /* The caller got what he wanted */        return p_block;    }    return 0; /* never reached */}/**************************************************************************** * Demux: ****************************************************************************/static int Demux( demux_t *p_demux ){    access_sys_t *p_sys = (access_sys_t *)p_demux->p_sys;    dshow_stream_t *p_stream = NULL;    VLCMediaSample sample;    int i_data_size, i_stream;    uint8_t *p_data;    block_t *p_block;    vlc_mutex_lock( &p_sys->lock );    /* Try to grab an audio sample (audio has a higher priority) */    for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )    {        p_stream = p_sys->pp_streams[i_stream];        if( p_stream->mt.majortype == MEDIATYPE_Audio &&            p_stream->p_capture_filter &&            p_stream->p_capture_filter->CustomGetPin()              ->CustomGetSample( &sample ) == S_OK )        {            break;        }    }    /* Try to grab a video sample */    if( i_stream == p_sys->i_streams )    {        for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )        {            p_stream = p_sys->pp_streams[i_stream];            if( p_stream->p_capture_filter &&                p_stream->p_capture_filter->CustomGetPin()                    ->CustomGetSample( &sample ) == S_OK )            {                break;            }        }    }    vlc_mutex_unlock( &p_sys->lock );    if( i_stream == p_sys->i_streams )    {        /* Sleep so we do not consume all the cpu, 10ms seems         * like a good value (100fps) */        msleep( 10000 );        return 1;    }    /*     * We got our sample     */    i_data_size = sample.p_sample->GetActualDataLength();    sample.p_sample->GetPointer( &p_data );    REFERENCE_TIME i_pts, i_end_date;    HRESULT hr = sample.p_sample->GetTime( &i_pts, &i_end_date );    if( hr != VFW_S_NO_STOP_TIME && hr != S_OK ) i_pts = 0;    if( !i_pts )    {        if( p_stream->mt.majortype == MEDIATYPE_Video || !p_stream->b_pts )        {            /* Use our data timestamp */            i_pts = sample.i_timestamp;            p_stream->b_pts = VLC_TRUE;        }    }    i_pts /= 10; /* Dshow works with 100 nano-seconds resolution */#if 0    msg_Dbg( p_demux, "Read() stream: %i, size: %i, PTS: "I64Fd,             i_stream, i_data_size, i_pts );#endif    p_block = block_New( p_demux, i_data_size );    p_demux->p_vlc->pf_memcpy( p_block->p_buffer, p_data, i_data_size );    p_block->i_pts = p_block->i_dts = i_pts;    sample.p_sample->Release();    es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_pts > 0 ? i_pts : 0 );    es_out_Send( p_demux->out, p_stream->p_es, p_block );    return 1;}/***************************************************************************** * AccessControl: *****************************************************************************/static int AccessControl( access_t *p_access, int i_query, va_list args ){    vlc_bool_t   *pb_bool;    int          *pi_int;    int64_t      *pi_64;    switch( i_query )    {    /* */    case ACCESS_CAN_SEEK:    case ACCESS_CAN_FASTSEEK:    case ACCESS_CAN_PAUSE:    case ACCESS_CAN_CONTROL_PACE:        pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );        *pb_bool = VLC_FALSE;        break;    /* */    case ACCESS_GET_MTU:        pi_int = (int*)va_arg( args, int * );        *pi_int = 0;        break;    case ACCESS_GET_PTS_DELAY:        pi_64 = (int64_t*)va_arg( args, int64_t * );        *pi_64 = (int64_t)var_GetInteger( p_access, "dshow-caching" ) * 1000;        break;    /* */    case ACCESS_SET_PAUSE_STATE:    case ACCESS_GET_TITLE_INFO:    case ACCESS_SET_TITLE:    case ACCESS_SET_SEEKPOINT:    case ACCESS_SET_PRIVATE_ID_STATE:        return VLC_EGENERIC;    default:        msg_Warn( p_access, "unimplemented query in control" );        return VLC_EGENERIC;    }    return VLC_SUCCESS;}/**************************************************************************** * DemuxControl: ****************************************************************************/static int DemuxControl( demux_t *p_demux, int i_query, va_list args ){    vlc_bool_t *pb;    int64_t    *pi64;    switch( i_query )    {    /* Special for access_demux */    case DEMUX_CAN_PAUSE:    case DEMUX_SET_PAUSE_STATE:    case DEMUX_CAN_CONTROL_PACE:        pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );        *pb = VLC_FALSE;        return VLC_SUCCESS;    case DEMUX_GET_PTS_DELAY:        pi64 = (int64_t*)va_arg( args, int64_t * );        *pi64 = (int64_t)var_GetInteger( p_demux, "dshow-caching" ) * 1000;        return VLC_SUCCESS;    case DEMUX_GET_TIME:        pi64 = (int64_t*)va_arg( args, int64_t * );        *pi64 = mdate();        return VLC_SUCCESS;    /* TODO implement others */    default:        return VLC_EGENERIC;    }    return VLC_EGENERIC;}/***************************************************************************** * config variable callback *****************************************************************************/static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,                               vlc_value_t newval, vlc_value_t oldval, void * ){    module_config_t *p_item;    vlc_bool_t b_audio = VLC_FALSE;    int i;    p_item = config_FindConfig( p_this, psz_name );    if( !p_item ) return VLC_SUCCESS;    if( !strcmp( psz_name, "dshow-adev" ) ) b_audio = VLC_TRUE;    /* Clear-up the current list */    if( p_item->i_list )    {        /* Keep the 2 first entries */        for( i = 2; i < p_item->i_list; i++ )        {            free( p_item->ppsz_list[i] );            free( p_item->ppsz_list_text[i] );        }        /* TODO: Remove when no more needed */        p_item->ppsz_list[i] = NULL;        p_item->ppsz_list_text[i] = NULL;    }    p_item->i_list = 2;    /* Find list of devices */    list<string> list_devices;    /* Initialize OLE/COM */    CoInitialize( 0 );    FindCaptureDevice( p_this, NULL, &list_devices, b_audio );    /* Uninitialize OLE/COM */    CoUninitialize();    if( !list_devices.size() ) return VLC_SUCCESS;    p_item->ppsz_list =        (char **)realloc( p_item->ppsz_list,                          (list_devices.size()+3) * sizeof(char *) );    p_item->ppsz_list_text =        (char **)realloc( p_item->ppsz_list_text,                          (list_devices.size()+3) * sizeof(char *) );    list<string>::iterator iter;    for( iter = list_devices.begin(), i = 2; iter != list_devices.end();         iter++, i++ )    {        p_item->ppsz_list[i] = strdup( iter->c_str() );        p_item->ppsz_list_text[i] = NULL;        p_item->i_list++;    }    p_item->ppsz_list[i] = NULL;    p_item->ppsz_list_text[i] = NULL;    /* Signal change to the interface */    p_i

⌨️ 快捷键说明

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