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

📄 dshow.cpp

📁 uclinux 下的vlc播放器源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            continue;        }        while( p_enummt->Next( 1, &p_mt, NULL ) == S_OK )        {            int i_current_fourcc = GetFourCCFromMediaType( *p_mt );            if( i_current_fourcc && p_mt->majortype == MEDIATYPE_Video                && p_mt->formattype == FORMAT_VideoInfo )            {                int i_current_width = ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biWidth;                int i_current_height = ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biHeight;                LONGLONG i_current_atpf = ((VIDEOINFOHEADER *)p_mt->pbFormat)->AvgTimePerFrame;                if( i_current_height < 0 )                    i_current_height = -i_current_height;                 msg_Dbg( p_this, "EnumDeviceCaps: input pin "                         "accepts chroma: %4.4s, width:%i, height:%i, fps:%f",                         (char *)&i_current_fourcc, i_current_width,                         i_current_height, (10000000.0f/((float)i_current_atpf)) );                if( ( !i_fourcc || i_fourcc == i_current_fourcc ) &&                    ( !i_width || i_width == i_current_width ) &&                    ( !i_height || i_height == i_current_height ) &&                    ( !i_AvgTimePerFrame || i_AvgTimePerFrame == i_current_atpf ) &&                    mt_count < mt_max )                {                    /* Pick match */                    mt[mt_count++] = *p_mt;                }                else FreeMediaType( *p_mt );            }            else if( i_current_fourcc && p_mt->majortype == MEDIATYPE_Audio                     && p_mt->formattype == FORMAT_WaveFormatEx)            {                int i_current_channels =                    ((WAVEFORMATEX *)p_mt->pbFormat)->nChannels;                int i_current_samplespersec =                    ((WAVEFORMATEX *)p_mt->pbFormat)->nSamplesPerSec;                int i_current_bitspersample =                    ((WAVEFORMATEX *)p_mt->pbFormat)->wBitsPerSample;                msg_Dbg( p_this, "EnumDeviceCaps: input pin "                         "accepts format: %4.4s, channels:%i, "                         "samples/sec:%i bits/sample:%i",                         (char *)&i_current_fourcc, i_current_channels,                         i_current_samplespersec, i_current_bitspersample);                if( (!i_channels || i_channels == i_current_channels) &&                    (!i_samplespersec ||                     i_samplespersec == i_current_samplespersec) &&                    (!i_bitspersample ||                     i_bitspersample == i_current_bitspersample) &&                    mt_count < mt_max )                {                    /* Pick  match */                    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: unsupported format "                         "(%s %4.4s)", psz_type, (char *)&p_mt->subtype );                FreeMediaType( *p_mt );            }            CoTaskMemFree( (PVOID)p_mt );        }        if( !mt_count && p_enummt->Reset() == S_OK )        {            // VLC did not find any supported MEDIATYPE for this output pin.            // However the graph builder might insert converter filters in            // the graph if we use a different codec in VLC filter input pin.            // however, in order to avoid nasty surprises, make use of this            // facility only for known unsupported codecs.            while( !mt_count && p_enummt->Next( 1, &p_mt, NULL ) == S_OK )            {                // the first four bytes of subtype GUID contains the codec FOURCC                const char *pfcc = (char *)&p_mt->subtype;                int i_current_fourcc = VLC_FOURCC(pfcc[0], pfcc[1], pfcc[2], pfcc[3]);                if( VLC_FOURCC('H','C','W','2') == i_current_fourcc                 && p_mt->majortype == MEDIATYPE_Video )                {                    // output format for 'Hauppauge WinTV PVR PCI II Capture'                    // try I420 as an input format                    i_current_fourcc = VLC_FOURCC('I','4','2','0');                    if( !i_fourcc || i_fourcc == i_current_fourcc )                    {                        // return alternative 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  = i_width > 0 ? i_width :                            ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biWidth;                          vh.bmiHeader.biHeight = i_height > 0 ? i_height :                            ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biHeight;                          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;                                       msg_Dbg( p_this, "EnumDeviceCaps: input pin media: using 'I420' in place of unsupported format 'HCW2'");                        if( SUCCEEDED(CopyMediaType(mt+mt_count, &mtr)) )                            ++mt_count;                    }                }                FreeMediaType( *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:

⌨️ 快捷键说明

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