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

📄 dshow.cpp

📁 video linux conference
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                // found it                                Found = TRUE;                            }                        }                        pKs->Release();                    }                    pinInfo.pFilter->Release();                }                pP->Release();            }            pins->Release();        }        return true;    }    else    {        IEnumPins *p_enumpins;        IPin *p_pin;        if( S_OK != p_filter->EnumPins( &p_enumpins ) ) return false;        while( S_OK == p_enumpins->Next( 1, &p_pin, NULL ) )        {            PIN_DIRECTION pin_dir;            p_pin->QueryDirection( &pin_dir );            if( pin_dir == PINDIR_OUTPUT &&                p_sys->p_graph->ConnectDirect( p_pin, (IPin *)p_input_pin,                                               0 ) == S_OK )            {                p_pin->Release();                p_enumpins->Release();                return true;            }            p_pin->Release();        }        p_enumpins->Release();        return false;    }}/* * get fourcc priority from arbritary preference, the higher the better */static int GetFourCCPriority( int i_fourcc ){    switch( i_fourcc )    {    case VLC_FOURCC('I','4','2','0'):    case VLC_FOURCC('f','l','3','2'):        return 9;    case VLC_FOURCC('Y','V','1','2'):    case VLC_FOURCC('a','r','a','w'):        return 8;    case VLC_FOURCC('R','V','2','4'):        return 7;    case VLC_FOURCC('Y','U','Y','2'):    case VLC_FOURCC('R','V','3','2'):    case VLC_FOURCC('R','G','B','A'):        return 6;    }    return 0;}#define MAX_MEDIA_TYPES 32static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,                       string devicename, vlc_bool_t b_audio ){    /* See if device is already opened */    for( int i = 0; i < p_sys->i_streams; i++ )    {        if( devicename.size() &&            p_sys->pp_streams[i]->devicename == devicename )        {            /* Already opened */            return VLC_SUCCESS;        }    }    list<string> list_devices;    /* Enumerate devices and display their names */    FindCaptureDevice( p_this, NULL, &list_devices, b_audio );    if( !list_devices.size() )        return VLC_EGENERIC;    list<string>::iterator iter;    for( iter = list_devices.begin(); iter != list_devices.end(); iter++ )        msg_Dbg( p_this, "found device: %s", iter->c_str() );    /* If no device name was specified, pick the 1st one */    if( devicename.size() == 0 )    {        devicename = *list_devices.begin();    }    // Use the system device enumerator and class enumerator to find    // a capture/preview device, such as a desktop USB video camera.    IBaseFilter *p_device_filter =        FindCaptureDevice( p_this, &devicename, 0, b_audio );    if( p_device_filter )        msg_Dbg( p_this, "using device: %s", devicename.c_str() );    else    {        msg_Err( p_this, "can't use device: %s, unsupported device type",                 devicename.c_str() );        return VLC_EGENERIC;    }    // Retreive acceptable media types supported by device    AM_MEDIA_TYPE media_types[MAX_MEDIA_TYPES];    size_t media_count =        EnumDeviceCaps( p_this, p_device_filter, p_sys->i_chroma,                        p_sys->i_width, p_sys->i_height,                        0, 0, 0, media_types, MAX_MEDIA_TYPES );    /* Find out if the pin handles MEDIATYPE_Stream, in which case we     * won't add a prefered media type as this doesn't seem to work well     * -- to investigate. */    vlc_bool_t b_stream_type = VLC_FALSE;    for( size_t i = 0; i < media_count; i++ )    {        if( media_types[i].majortype == MEDIATYPE_Stream )        {            b_stream_type = VLC_TRUE;            break;        }    }    size_t mt_count = 0;    AM_MEDIA_TYPE *mt = NULL;    if( !b_stream_type && !b_audio )    {        // Insert prefered video media type        AM_MEDIA_TYPE mtr;        VIDEOINFOHEADER vh;        mtr.majortype            = MEDIATYPE_Video;        mtr.subtype              = MEDIASUBTYPE_I420;        mtr.bFixedSizeSamples    = TRUE;        mtr.bTemporalCompression = FALSE;        mtr.pUnk                 = NULL;        mtr.formattype           = FORMAT_VideoInfo;        mtr.cbFormat             = sizeof(vh);        mtr.pbFormat             = (BYTE *)&vh;        memset(&vh, 0, sizeof(vh));        vh.bmiHeader.biSize   = sizeof(vh.bmiHeader);        vh.bmiHeader.biWidth  = p_sys->i_width > 0 ? p_sys->i_width : 320;        vh.bmiHeader.biHeight = p_sys->i_height > 0 ? p_sys->i_height : 240;        vh.bmiHeader.biPlanes      = 3;        vh.bmiHeader.biBitCount    = 12;        vh.bmiHeader.biCompression = VLC_FOURCC('I','4','2','0');        vh.bmiHeader.biSizeImage   = vh.bmiHeader.biWidth * 12 *            vh.bmiHeader.biHeight / 8;        mtr.lSampleSize            = vh.bmiHeader.biSizeImage;        mt_count = 1;        mt = (AM_MEDIA_TYPE *)malloc( sizeof(AM_MEDIA_TYPE)*mt_count );        CopyMediaType(mt, &mtr);    }    else if( !b_stream_type )    {        // Insert prefered audio media type        AM_MEDIA_TYPE mtr;        WAVEFORMATEX wf;        mtr.majortype            = MEDIATYPE_Audio;        mtr.subtype              = MEDIASUBTYPE_PCM;        mtr.bFixedSizeSamples    = TRUE;        mtr.bTemporalCompression = FALSE;        mtr.lSampleSize          = 0;        mtr.pUnk                 = NULL;        mtr.formattype           = FORMAT_WaveFormatEx;        mtr.cbFormat             = sizeof(wf);        mtr.pbFormat             = (BYTE *)&wf;        memset(&wf, 0, sizeof(wf));        wf.wFormatTag = WAVE_FORMAT_PCM;        wf.nChannels = 2;        wf.nSamplesPerSec = 44100;        wf.wBitsPerSample = 16;        wf.nBlockAlign = wf.nSamplesPerSec * wf.wBitsPerSample / 8;        wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;        wf.cbSize = 0;        mt_count = 1;        mt = (AM_MEDIA_TYPE *)malloc( sizeof(AM_MEDIA_TYPE)*mt_count );        CopyMediaType(mt, &mtr);    }    if( media_count > 0 )    {        mt = (AM_MEDIA_TYPE *)realloc( mt, sizeof(AM_MEDIA_TYPE) *                                       (mt_count + media_count) );        // Order and copy returned media types according to arbitrary        // fourcc priority        for( size_t c = 0; c < media_count; c++ )        {            int slot_priority =                GetFourCCPriority(GetFourCCFromMediaType(media_types[c]));            size_t slot_copy = c;            for( size_t d = c+1; d < media_count; d++ )            {                int priority =                    GetFourCCPriority(GetFourCCFromMediaType(media_types[d]));                if( priority > slot_priority )                {                    slot_priority = priority;                    slot_copy = d;                }            }            if( slot_copy != c )            {                mt[c+mt_count] = media_types[slot_copy];                media_types[slot_copy] = media_types[c];            }            else            {                mt[c+mt_count] = media_types[c];            }        }        mt_count += media_count;    }    /* Create and add our capture filter */    CaptureFilter *p_capture_filter =        new CaptureFilter( p_this, p_sys, mt, mt_count );    p_sys->p_graph->AddFilter( p_capture_filter, 0 );    /* Add the device filter to the graph (seems necessary with VfW before     * accessing pin attributes). */    p_sys->p_graph->AddFilter( p_device_filter, 0 );    /* Attempt to connect one of this device's capture output pins */    msg_Dbg( p_this, "connecting filters" );    if( ConnectFilters( p_this, p_sys, p_device_filter, p_capture_filter ) )    {        /* Success */        msg_Dbg( p_this, "filters connected successfully !" );        dshow_stream_t dshow_stream;        dshow_stream.b_pts = VLC_FALSE;        dshow_stream.p_es = 0;        dshow_stream.mt =            p_capture_filter->CustomGetPin()->CustomGetMediaType();        /* Show Device properties. Done here so the VLC stream is setup with         * the proper parameters. */        vlc_value_t val;        var_Get( p_this, "dshow-config", &val );        if( val.b_bool )        {            ShowDeviceProperties( p_this, p_sys->p_capture_graph_builder2,                                  p_device_filter, b_audio );        }        ConfigTuner( p_this, p_sys->p_capture_graph_builder2,                     p_device_filter );        var_Get( p_this, "dshow-tuner", &val );        if( val.b_bool && dshow_stream.mt.majortype != MEDIATYPE_Stream )        {            /* FIXME: we do MEDIATYPE_Stream later so we don't do it twice. */            ShowTunerProperties( p_this, p_sys->p_capture_graph_builder2,                                 p_device_filter, b_audio );        }        dshow_stream.mt =            p_capture_filter->CustomGetPin()->CustomGetMediaType();        dshow_stream.i_fourcc = GetFourCCFromMediaType( dshow_stream.mt );        if( dshow_stream.i_fourcc )        {            if( dshow_stream.mt.majortype == MEDIATYPE_Video )            {                dshow_stream.header.video =                    *(VIDEOINFOHEADER *)dshow_stream.mt.pbFormat;                msg_Dbg( p_this, "MEDIATYPE_Video" );                msg_Dbg( p_this, "selected video pin accepts format: %4.4s",                         (char *)&dshow_stream.i_fourcc);            }            else if( dshow_stream.mt.majortype == MEDIATYPE_Audio )            {                dshow_stream.header.audio =                    *(WAVEFORMATEX *)dshow_stream.mt.pbFormat;                msg_Dbg( p_this, "MEDIATYPE_Audio" );                msg_Dbg( p_this, "selected audio pin accepts format: %4.4s",                         (char *)&dshow_stream.i_fourcc);            }            else if( dshow_stream.mt.majortype == MEDIATYPE_Stream )            {                msg_Dbg( p_this, "MEDIATYPE_Stream" );                msg_Dbg( p_this, "selected stream pin accepts format: %4.4s",                         (char *)&dshow_stream.i_fourcc);            }            else            {                msg_Dbg( p_this, "unknown stream majortype" );                goto fail;            }            /* Add directshow elementary stream to our list */            dshow_stream.p_device_filter = p_device_filter;            dshow_stream.p_capture_filter = p_capture_filter;            p_sys->pp_streams = (dshow_stream_t **)realloc( p_sys->pp_streams,                sizeof(dshow_stream_t *) * (p_sys->i_streams + 1) );            p_sys->pp_streams[p_sys->i_streams] = new dshow_stream_t;            *p_sys->pp_streams[p_sys->i_streams++] = dshow_stream;            return VLC_SUCCESS;        }    } fail:    /* Remove filters from graph */    p_sys->p_graph->RemoveFilter( p_device_filter );    p_sys->p_graph->RemoveFilter( p_capture_filter );    /* Release objects */    p_device_filter->Release();    p_capture_filter->Release();    return VLC_EGENERIC;}static IBaseFilter *FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,                   list<string> *p_listdevices, vlc_bool_t b_audio ){    IBaseFilter *p_base_filter = NULL;    IMoniker *p_moniker = NULL;    ULONG i_fetched;    HRESULT hr;    /* Create the system device enumerator */    ICreateDevEnum *p_dev_enum = NULL;    hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,                           IID_ICreateDevEnum, (void **)&p_dev_enum );    if( FAILED(hr) )    {        msg_Err( p_this, "failed to create the device enumerator (0x%lx)", hr);        return NULL;    }    /* Create an enumerator for the video capture devices */    IEnumMoniker *p_class_enum = NULL;

⌨️ 快捷键说明

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