Compartir a través de


Configurar el formato de salida de vídeo

[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.

Nota:

La funcionalidad descrita en este tema está en desuso. Para configurar el formato de salida de un dispositivo de captura, una aplicación debe usar la estructura de AM_MEDIA_TYPE devuelta por IAMStreamConfig::GetFormat en el parámetro pmt .

 

Un dispositivo de captura puede admitir un intervalo de formatos de salida. Por ejemplo, un dispositivo podría admitir RGB de 16 bits, RGB de 32 bits y YUYV. Dentro de cada uno de estos formatos, el dispositivo puede admitir un intervalo de tamaños de fotograma.

En un dispositivo WDM, la interfaz IAMStreamConfig se usa para notificar qué formato admite el dispositivo y para establecer el formato. (Para los dispositivos VFW heredados, use el cuadro de diálogo Formato de vídeo VFW, como se describe en Mostrar cuadros de diálogo de captura de VFW). La interfaz IAMStreamConfig se expone en el pin de captura del filtro de captura, el pin de vista previa o ambos. Use el método ICaptureGraphBuilder2::FindInterface para obtener el puntero de interfaz:

IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
    &PIN_CATEGORY_PREVIEW, // Preview pin.
    0,    // Any media type.
    pCap, // Pointer to the capture filter.
    IID_IAMStreamConfig, (void**)&pConfig);

El dispositivo tiene una lista de tipos de medios que admite. Para cada tipo de medio, el dispositivo también proporciona un conjunto de funcionalidades. Estos incluyen el intervalo de tamaños de fotograma que están disponibles para ese formato, cómo el dispositivo puede estirar o reducir la imagen, y el intervalo de velocidades de fotogramas.

Para obtener el número de tipos multimedia, llame al método IAMStreamConfig::GetNumberOfCapabilities . El método devuelve dos valores:

  • Número de tipos de medios.
  • Tamaño de la estructura que contiene la información de las funcionalidades.

El valor de tamaño es necesario porque la interfaz IAMStreamConfig se usa para audio y vídeo (y se puede extender a otros tipos multimedia). En el caso del vídeo, las funcionalidades se describen mediante la estructura de VIDEO_STREAM_CONFIG_CAPS , mientras que el audio usa la estructura AUDIO_STREAM_CONFIG_CAPS .

Para enumerar los tipos multimedia, llame al método IAMStreamConfig::GetStreamCaps con un índice de base cero. El método GetStreamCaps devuelve un tipo de medio y la estructura de funcionalidad correspondiente:

int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);

// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
    // Use the video capabilities structure.

    for (int iFormat = 0; iFormat < iCount; iFormat++)
    {
        VIDEO_STREAM_CONFIG_CAPS scc;
        AM_MEDIA_TYPE *pmtConfig;
        hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
        if (SUCCEEDED(hr))
        {
            /* Examine the format, and possibly use it. */

            // Delete the media type when you are done.
            DeleteMediaType(pmtConfig);
        }
}

Observe cómo se asignan las estructuras para el método GetStreamCaps . El método asigna la estructura de tipo de medio, mientras que el autor de la llamada asigna la estructura de funcionalidades. Convertir la estructura de funcionalidades en un puntero de matriz de bytes. Una vez que haya terminado con el tipo de medio, elimine la estructura de AM_MEDIA_TYPE , junto con el bloque de formato del tipo de medio.

Puede configurar el dispositivo para que use un formato devuelto en el método GetStreamCaps . Simplemente llame a IAMStreamConfig::SetFormat con el tipo de medio:

hr = pConfig->SetFormat(pmtConfig);

Si el pin no está conectado, intentará usar este formato cuando se conecte. Si el pin ya está conectado, intenta volver a conectarse con el nuevo formato. En cualquier caso, es posible que el filtro de bajada rechace el formato.

También puede modificar el tipo de medio antes de pasarlo al método SetFormat . Aquí es donde entra en VIDEO_STREAM_CONFIG_CAPS estructura. Describe todas las formas válidas de cambiar el tipo de medio. Para usar esta información, debe comprender los detalles de ese tipo de medio determinado.

Por ejemplo, supongamos que GetStreamCaps devuelve un formato RGB de 24 bits, con un tamaño de marco de 320 x 240 píxeles. Puede obtener esta información examinando el tipo principal, el subtipo y el bloque de formato del tipo de medio:

if ((pmtConfig.majortype == MEDIATYPE_Video) &&
    (pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
    (pmtConfig.formattype == FORMAT_VideoInfo) &&
    (pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
    (pmtConfig.pbFormat != NULL))
{
    VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
    // pVih contains the detailed format information.
    LONG lWidth = pVih->bmiHeader.biWidth;
    LONG lHeight = pVih->bmiHeader.biHeight;
}

La estructura VIDEO_STREAM_CONFIG_CAPS proporciona el ancho y alto mínimo y máximo que se puede usar para este tipo de medio. También proporciona el tamaño del "paso", que define los incrementos por los que puede ajustar el ancho o alto. Por ejemplo, el dispositivo podría devolver lo siguiente:

  • MinOutputSize: 160 x 120
  • MaxOutputSize: 320 x 240
  • OutputGranularityX: 8 píxeles (tamaño de paso horizontal)
  • OutputGranularityY: 8 píxeles (tamaño de paso vertical)

Dados estos números, puede establecer el ancho en cualquier elemento del intervalo (160, 168, 176, ... 304, 312, 320) y la altura a cualquier elemento del rango (120, 128, 136, ... 104, 112, 120). En el siguiente diagrama se muestra este proceso.

tamaños de formato de vídeo

Para establecer un nuevo tamaño de marco, modifique directamente la estructura de AM_MEDIA_TYPE devuelta en GetStreamCaps:

pVih->bmiHeader.biWidth = 160;
pVih->bmiHeader.biHeight = 120;
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);

A continuación, pase el tipo de medio al método SetFormat , como se ha descrito anteriormente.

Los miembros MinFrameInterval y MaxFrameInterval de VIDEO_STREAM_CONFIG_CAPS son la longitud mínima y máxima de cada fotograma de vídeo, que puede traducir en velocidades de fotogramas de la siguiente manera:

frames per second = 10,000,000 / frame duration

Para solicitar una velocidad de fotogramas determinada, modifique el valor de AvgTimePerFrame en la estructura VIDEOINFOHEADER o VIDEOINFOHEADER2 en el tipo de medio. Es posible que el dispositivo no admita todos los valores posibles entre el mínimo y el máximo, por lo que el controlador usará el valor más cercano que pueda. Para ver qué valor usó realmente el controlador, llame a IAMStreamConfig::GetFormat después de llamar a SetFormat.

Algunos controladores pueden notificar MAXLONGLONG (0x7FFFFFFFFFFFFFFF) para el valor de MaxFrameInterval, lo que significa que no hay ninguna duración máxima. Sin embargo, es posible que desee aplicar una velocidad de fotogramas mínima en la aplicación, como 1 fps.

Acerca de los tipos de medios

Configuración de un dispositivo de captura de vídeo