Vista previa del audio de TV
[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.
Para obtener una vista previa del audio del televisor, enrute el pin de descodificador de audio en el filtro de barra transversal al pin de tuner de audio. Para silenciar el audio, enrute el pin del descodificador de audio a -1, como se muestra en el diagrama siguiente. (Los filtros de barra cruzada se describen en Trabajar con barras cruzadas).
El enfoque básico es el siguiente:
- Use el método ICaptureGraphBuilder2::FindInterface para buscar el filtro de barra cruzada.
- Use el método IAMCrossbar::get_CrossbarPinInfo para enumerar los pines de entrada y salida del filtro de barra cruzada. Busque un pin de salida del descodificador de audio y un pin de entrada de tuner de audio.
- Si encuentra los pines correctos, llame a IAMCrossbar::Route para enrutar los patillas. Si no es así, busque otra barra transversal y repita el proceso.
- Para silenciar el audio, enrute el descodificador de audio a -1.
La mayoría de los tuerdores de TV usan un único filtro de barra transversal, pero algunos usan dos filtros de barra transversal. Por lo tanto, es posible que tenga que buscar una segunda barra cruzada si se produce un error en la primera.
Nota:
Al contrario de lo que podría esperar, no se requiere ningún filtro de captura de audio o representador de audio para obtener una vista previa del audio, ya que hay una conexión física entre la tarjeta de tuner y la tarjeta de sonido.
En el código siguiente se muestran estos pasos con más detalle. En primer lugar, esta es una función auxiliar que busca un filtro de barra cruzada para un tipo de patilla especificado:
HRESULT FindCrossbarPin(
IAMCrossbar *pXBar, // Pointer to the crossbar.
PhysicalConnectorType PhysicalType, // Pin type to match.
PIN_DIRECTION Dir, // Pin direction.
long *pIndex) // Receives the index of the pin, if found.
{
BOOL bInput = (Dir == PINDIR_INPUT ? TRUE : FALSE);
// Find out how many pins the crossbar has.
long cOut, cIn;
HRESULT hr = pXBar->get_PinCounts(&cOut, &cIn);
if (FAILED(hr)) return hr;
// Enumerate pins and look for a matching pin.
long count = (bInput ? cIn : cOut);
for (long i = 0; i < count; i++)
{
long iRelated = 0;
long ThisPhysicalType = 0;
hr = pXBar->get_CrossbarPinInfo(bInput, i, &iRelated,
&ThisPhysicalType);
if (SUCCEEDED(hr) && ThisPhysicalType == PhysicalType)
{
// Found a match, return the index.
*pIndex = i;
return S_OK;
}
}
// Did not find a matching pin.
return E_FAIL;
}
La siguiente función intenta activar o silenciar el audio, en función del valor del parámetro bActivate . Busca en los pins necesarios el filtro de barra cruzada especificado. Si no los encuentra, devuelve un código de error.
HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate)
{
// Look for the Audio Decoder output pin.
long i = 0;
HRESULT hr = FindCrossbarPin(pXBar, PhysConn_Audio_AudioDecoder,
PINDIR_OUTPUT, &i);
if (SUCCEEDED(hr))
{
if (bActivate) // Activate the audio.
{
// Look for the Audio Tuner input pin.
long j = 0;
hr = FindCrossbarPin(pXBar, PhysConn_Audio_Tuner,
PINDIR_INPUT, &j);
if (SUCCEEDED(hr))
{
return pXBar->Route(i, j);
}
}
else // Mute the audio
{
return pXBar->Route(i, -1);
}
}
return E_FAIL;
}
La siguiente función busca en el gráfico de filtros un filtro de barra cruzada. Si encuentra una, intenta activar o silenciar el audio (mediante la función anterior). Si se produce un error en esa operación, el método busca una segunda barra cruzada y vuelve a intentarlo. Para obtener un enfoque más generalizado para administrar varios filtros de barra cruzada en un grafo, consulte la clase CCrossbar en la aplicación de ejemplo AmCap.
HRESULT ActivateAudio(ICaptureGraphBuilder2 *pBuild, IBaseFilter *pSrc,
BOOL bActivate)
{
// Search upstream for a crossbar.
IAMCrossbar *pXBar1 = NULL;
HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
IID_IAMCrossbar, (void**)&pXBar1);
if (SUCCEEDED(hr))
{
hr = ConnectAudio(pXBar1, bActivate);
if (FAILED(hr))
{
// Look for another crossbar.
IBaseFilter *pF = NULL;
hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pF);
if (SUCCEEDED(hr))
{
// Search upstream for another one.
IAMCrossbar *pXBar2 = NULL;
hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pF,
IID_IAMCrossbar, (void**)&pXBar2);
pF->Release();
if (SUCCEEDED(hr))
{
hr = ConnectAudio(pXBar2, bActivate);
pXBar2->Release();
}
}
}
pXBar1->Release();
}
return hr;
}
En el código siguiente se muestra cómo llamar a estas funciones:
// Build the analog TV graph (not shown).
// Activate the audio.
hr = ActivateAudio(pBuild, pCap, TRUE);
// Later, mute the audio.
hr = ActivateAudio(pBuild, pCap, FALSE);
Tenga en cuenta que estas funciones de ejemplo repiten muchas de las mismas llamadas de función. Por ejemplo, enumeran las patillas de la barra cruzada cada vez. En una aplicación real, puede almacenar en caché parte de esta información.
Temas relacionados