Condividi tramite


Come impostare il formato di acquisizione video

Un dispositivo di acquisizione video può supportare diversi formati di acquisizione. I formati in genere differiscono in base al tipo di compressione, lo spazio dei colori (YUV o RGB), le dimensioni del frame o la frequenza dei fotogrammi.

L'elenco dei formati supportati è contenuto nel descrittore di presentazione. Per altre informazioni, vedere Descrittori di presentazione.

Per enumerare i formati supportati:

  1. Creare l'origine multimediale per il dispositivo di acquisizione. Vedere enumerazione dei dispositivi di acquisizione video.
  2. Chiamare FMIMediaSource::CreatePresentationDescriptor nell'origine multimediale per ottenere il descrittore di presentazione.
  3. Chiamare IMFPresentationDescriptor::GetStreamDescriptorByIndex per ottenere il descrittore di flusso per il flusso video.
  4. Chiamare FMStreamDescriptor::GetMediaTypeHandler nel descrittore di flusso.
  5. Chiamare IMFMediaTypeHandler::GetMediaTypeCount per ottenere il numero di formati supportati.
  6. In un ciclo chiamare IMFMediaTypeHandler::GetMediaTypeByIndex per ottenere ogni formato. Il formato è rappresentato da un tipo di supporto. Per altre informazioni, vedere Tipi di supporti video.

Nell'esempio seguente vengono enumerati i formati di acquisizione per un dispositivo:

HRESULT EnumerateCaptureFormats(IMFMediaSource *pSource)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    DWORD cTypes = 0;
    hr = pHandler->GetMediaTypeCount(&cTypes);
    if (FAILED(hr))
    {
        goto done;
    }

    for (DWORD i = 0; i < cTypes; i++)
    {
        hr = pHandler->GetMediaTypeByIndex(i, &pType);
        if (FAILED(hr))
        {
            goto done;
        }

        LogMediaType(pType);
        OutputDebugString(L"\n");

        SafeRelease(&pType);
    }

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

La LogMediaType funzione usata in questo esempio è elencata nell'argomento Media Type Debug Code.

Per impostare il formato di acquisizione:

  1. Ottenere un puntatore all'interfaccia IMFMediaTypeHandler , come illustrato nell'esempio precedente.
  2. Chiamare IMFMediaTypeHandler::GetMediaTypeByIndex per ottenere il formato desiderato, specificato dall'indice.
  3. Chiamare IMFMediaTypeHandler::SetCurrentMediaType per impostare il formato.

Se non si imposta il formato di acquisizione, il dispositivo userà il formato predefinito.

Nell'esempio seguente viene impostato il formato di acquisizione:

HRESULT SetDeviceFormat(IMFMediaSource *pSource, DWORD dwFormatIndex)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->GetMediaTypeByIndex(dwFormatIndex, &pType);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->SetCurrentMediaType(pType);

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

L'ordine in cui vengono restituiti i formati dipende dal dispositivo. In genere, vengono raggruppati prima per tipo di compressione o spazio colore; e quindi dalle dimensioni più piccole del frame alle dimensioni più grandi del frame all'interno di ogni gruppo.

La frequenza dei fotogrammi viene gestita leggermente diversamente rispetto agli altri attributi di formato. Per altre informazioni, vedere Come impostare la frequenza dei fotogrammi di acquisizione video.

Nota

In alcuni dispositivi l'elenco di formato conterrà una voce duplicata per ogni formato. Ad esempio, se il dispositivo supporta 15 formati di acquisizione distinti, l'elenco conterrà 30 voci. All'interno di ogni coppia, uno dei tipi multimediali avrà l'attributo MF_MT_AM_FORMAT_TYPE uguale a FORMAT_VideoInfo e l'altro avrà MF_MT_AM_FORMAT_TYPEuguale a FORMAT_VideoInfo2. Questi due valori sono definiti nel file di intestazione uuids.h.) Il secondo tipo può contenere anche informazioni sul colore aggiuntive (Informazioni sul colore estese) o visualizzare un valore diverso per l'interlacciamento (MF_MT_INTERLACE_MODE). Questi tipi duplicati esistono per supportare applicazioni DirectShow meno recenti. In un'applicazione Media Foundation è necessario ignorare il tipo di FORMAT_VideoInfo ogni volta che viene elencato un tipo di FORMAT_VideoInfo2 duplicato.

 

Acquisizione video