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

📄 dshow.cpp

📁 VLC Player Source Code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                }                                // Set the sample size and image size.                                // (Round the image width up to a DWORD boundary.)                                p_mt->lSampleSize = pVih->bmiHeader.biSizeImage =                                    ((pVih->bmiHeader.biWidth + 3) & ~3) *                                    pVih->bmiHeader.biHeight * (pVih->bmiHeader.biBitCount>>3);                                // no cropping, use full video input buffer                                memset(&(pVih->rcSource), 0, sizeof(RECT));                                memset(&(pVih->rcTarget), 0, sizeof(RECT));                                // select this format as default                                if( SUCCEEDED( pSC->SetFormat(p_mt) ) )                                {                                    i_priority = i_current_priority;                                    if( i_fourcc )                                        // no need to check any more media types                                        i = piCount;                                }                            }                            else if( p_mt->majortype == MEDIATYPE_Audio                                    && p_mt->formattype == FORMAT_WaveFormatEx )                            {                                AUDIO_STREAM_CONFIG_CAPS *pASCC = reinterpret_cast<AUDIO_STREAM_CONFIG_CAPS*>(pSCC);                                WAVEFORMATEX *pWfx = reinterpret_cast<WAVEFORMATEX*>(p_mt->pbFormat);                                if( i_current_fourcc && (WAVE_FORMAT_PCM == pWfx->wFormatTag) )                                {                                    int val = i_channels;                                    if( ! val )                                        val = 2;                                    if( val % pASCC->ChannelsGranularity                                     || (unsigned int)val < pASCC->MinimumChannels                                     || (unsigned int)val > pASCC->MaximumChannels )                                    {                                        // required number channels not available, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pWfx->nChannels = val;                                    val = i_samplespersec;                                    if( ! val )                                        val = 44100;                                    if( val % pASCC->SampleFrequencyGranularity                                     || (unsigned int)val < pASCC->MinimumSampleFrequency                                     || (unsigned int)val > pASCC->MaximumSampleFrequency )                                    {                                        // required sampling rate not available, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pWfx->nSamplesPerSec = val;                                     val = i_bitspersample;                                    if( ! val )                                    {                                        if( VLC_FOURCC('f', 'l', '3', '2') == i_current_fourcc )                                            val = 32;                                        else                                            val = 16;                                    }                                    if( val % pASCC->BitsPerSampleGranularity                                     || (unsigned int)val < pASCC->MinimumBitsPerSample                                     || (unsigned int)val > pASCC->MaximumBitsPerSample )                                    {                                        // required sample size not available, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pWfx->wBitsPerSample = val;                                    pWfx->nBlockAlign = (pWfx->wBitsPerSample * pWfx->nChannels)/8;                                    pWfx->nAvgBytesPerSec = pWfx->nSamplesPerSec * pWfx->nBlockAlign;                                    // select this format as default                                    if( SUCCEEDED( pSC->SetFormat(p_mt) ) )                                    {                                        i_priority = i_current_priority;                                    }                                }                            }                            FreeMediaType( *p_mt );                            CoTaskMemFree( (PVOID)p_mt );                        }                    }                    CoTaskMemFree( (LPVOID)pSCC );                    if( i_priority >= 0 )                        msg_Dbg( p_this, "EnumDeviceCaps: input pin default format configured");                }            }            pSC->Release();        }        /*        ** Probe pin for available medias (may be a previously configured one)        */        if( FAILED( p_output_pin->EnumMediaTypes( &p_enummt ) ) )        {            p_output_pin->Release();            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( !vlc_object_alive (p_access) || 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;        }        samp

⌨️ 快捷键说明

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