Bagikan melalui


Mengatur Jenis Media pada DMO

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Tangkapan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine dan Audio/Video Capture di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

Sebelum DMO dapat memproses data apa pun, klien harus mengatur jenis media untuk setiap aliran. (Ada satu pengecualian kecil untuk aturan ini; lihat Aliran Opsional.) Untuk menemukan jumlah aliran, panggil metode IMediaObject::GetStreamCount :

DWORD cInput = 0, cOutput = 0;
pDMO->GetStreamCount(&cInput, &cOutput);

Metode ini mengembalikan dua nilai, jumlah input dan jumlah output. Nilai-nilai ini diperbaiki untuk masa pakai DMO.

Jenis Pilihan

Untuk setiap aliran, DMO menetapkan daftar kemungkinan jenis media, dalam urutan preferensi. Misalnya, jenis pilihan mungkin 32-RGB, RGB 24-bit, dan RGB 16-bit, dalam urutan tersebut. Ketika klien mengatur jenis media, klien dapat menggunakan daftar ini sebagai petunjuk. Untuk mengambil jenis yang disukai untuk aliran, panggil metode IMediaObject::GetInputType atau metode IMediaObject::GetOutputType . Tentukan nomor aliran dan nilai indeks untuk jenis (mulai dari nol). Misalnya, kode berikut mengambil jenis pilihan pertama dari aliran input pertama:

DMO_MEDIA_TYPE mt
hr = pDMO->GetInputType(0, 0, &mt)
if (SUCCEEDED(hr))
{
    // Examine this media type (not shown).
    /* ... */

    // Free the format block.
    MoFreeMediaType(&mt);
}

Untuk menghitung semua jenis media pilihan pada aliran tertentu, gunakan perulangan yang meningkatkan indeks jenis hingga metode mengembalikan DMO_E_NO_MORE_ITEMS, seperti yang ditunjukkan dalam contoh berikut:

DMO_MEDIA_TYPE mt;
DWORD dwType = 0;
while (hr = pDMO->GetInputType(0, dwType, &mt), SUCCEEDED(hr))
{
    // Examine this media type (not shown).
    /* ... */

    // Free the format block.
    MoFreeMediaType(&mt);
    ++dwType;
}

Anda harus mencatat poin-poin berikut tentang jenis pilihan:

  • DMO mungkin mengembalikan jenis yang tidak memiliki blok format. Misalnya, DMO dapat menentukan jenis video, seperti RGB 24-bit, tanpa memberikan lebar dan tinggi gambar. Namun, ketika Anda mengatur jenisnya, Anda harus menyediakan blok format lengkap. (Beberapa jenis media, seperti MIDI, tidak pernah memerlukan blok format, dalam hal ini keterangan tidak berlaku.)
  • DMO tidak diperlukan untuk mendukung setiap kombinasi jenis pilihan yang dikembalikannya. Misalnya, jika DMO memiliki dua aliran, dan setiap aliran memiliki empat jenis pilihan, ada 16 kemungkinan kombinasi, tetapi tidak semuanya dijamin valid.
  • Ketika klien mengatur jenis media untuk satu aliran, DMO mungkin memperbarui jenis pilihan untuk aliran lain untuk mencerminkan status baru. Namun, tidak diharuskan untuk melakukannya.
  • Untuk beberapa aliran, DMO mungkin tidak menawarkan jenis pilihan apa pun. Biasanya, DMO harus menawarkan setidaknya beberapa jenis pilihan pada beberapa aliran.
  • DMO tidak diperlukan untuk menawarkan daftar lengkap jenis media yang dapat diterimanya. Mungkin ada jenis "tidak terpuaskan" yang didukung DMO tetapi tidak menawarkan sebagai jenis yang disukai.

Singkatnya, klien harus memperlakukan jenis yang disukai sebagai pedoman saja. Satu-satunya cara untuk mengetahui jenis mana yang didukung adalah dengan mengujinya, seperti yang dijelaskan di bagian berikutnya.

Mengatur Jenis Media pada Aliran

Gunakan metode IMediaObject::SetInputType dan IMediaObject::SetOutputType untuk mengatur jenis untuk setiap aliran. Anda harus menyediakan struktur DMO_MEDIA_TYPE yang berisi deskripsi lengkap tipe media. Contoh berikut mengatur jenis media pada aliran input 0, menggunakan audio PCM stereo 44,1-kHz 16-bit:

DMO_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(DMO_MEDIA_TYPE));
// Allocate memory for the format block.
HRESULT hr = MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
if (SUCCEEDED(hr))
{
    // Set the type GUIDs.
    mt.majortype  = MEDIATYPE_Audio;
    mt.subtype    = MEDIASUBTYPE_PCM;
    mt.formattype = FORMAT_WaveFormatEx;

    // Initialize the format block.
    WAVEFORMATEX *pWave = reinterpret_cast<WAVEFORMATEX*>(mt.pbFormat);
    pWave->wFormatTag = WAVE_FORMAT_PCM;
    pWave->nChannels = 2;
    pWave->nSamplesPerSec = 44100;
    pWave->wBitsPerSample = 16;
    pWave->nBlockAlign = (pWave->nChannels * pWave->wBitsPerSample) / 8;
    pWave->nAvgBytesPerSec = pWave->nSamplesPerSec * pWave->nBlockAlign;
    pWave->cbSize = 0;

    // Set the media type.
    hr = pDMO->SetInputType(0, &mt, 0); 

    // Release the format block.
    MoFreeMediaType(&mt);
}

Untuk menguji jenis media tanpa mengaturnya, panggil SetInputType atau SetOutputType dengan bendera DMO_SET_TYPEF_TEST_ONLY. Metode mengembalikan S_OK jika jenisnya dapat diterima, atau S_FALSE sebaliknya:

if (S_OK == pDMO->SetInputType(0, &mt, DMO_SET_TYPEF_TEST_ONLY)
{
    // Media type is OK.
}

Karena pengaturan pada satu aliran dapat memengaruhi aliran lain, Anda mungkin perlu menghapus jenis media streaming. Untuk melakukan ini, panggil SetInputType atau SetOutputType dengan bendera DMO_SET_TYPEF_CLEAR.

Untuk DMO dekoder, klien biasanya akan mengatur jenis input terlebih dahulu, lalu memilih jenis output. Untuk DMO encoder, klien akan mengatur jenis output terlebih dahulu, lalu jenis input.

Langsung Hosting DMO