📄 dshow.cpp
字号:
} // 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 + -