Aracılığıyla paylaş


Temel MFT İşleme Modeli

Bu konuda, istemcinin verileri işlemek için Media Foundation dönüşümünü (MFT) nasıl kullandığı açıklanmaktadır. istemcisi, MFT'de yöntemleri doğrudan çağıran herhangi bir şeydir. Bu uygulama veya Media Foundation işlem hattı olabilir.

Şu durumdaysanız bu konuyu okuyun:

  • Bir veya daha fazla MFT'ye doğrudan çağrı yapan bir uygulama yazma.
  • Özel bir MFT yazmak ve bir MFT'nin beklenen davranışını anlamak istiyorum.

Bu konuda zaman uyumlu işleme modeli açıklanmaktadır. Bu modelde, tüm veri işleme yöntemleri tamamlanana kadar durur. MFT'ler, Asenkron MFT'lerkonusunda açıklanan asenkron modeli de destekleyebilir.

Temel İşleme Modeli

MFT'yi oluştur

MFT oluşturmanın birkaç yolu vardır:

  • MFTEnum işlevini çağırın.
  • MFTEnumEx işlevini çağırın.
  • MFT'nin CLSID'sini zaten biliyorsanız CoCreateInstanceçağrısı yapmanız yeterlidir.

Bazı MFT'ler özel oluşturma işlevi gibi başka seçenekler sağlayabilir.

Akış Tanımlayıcılarını Alma

MFT, bir veya daha fazla akışınasahiptir. Giriş akışları giriş verilerini alır ve çıkış akışları çıkış verileri oluşturur. Akışlar ayrı nesneler olarak temsil edilmemektedir. Bunun yerine, çeşitli MFT yöntemleri akış tanımlayıcılarını parametre olarak alır.

Bazı MFT'ler istemcinin giriş akışları eklemesine veya kaldırmasına olanak sağlar. Akış sırasında, MFT çıkış akışları ekleyebilir veya kaldırabilir. (İstemci çıkış akışları ekleyemez veya kaldıramaz.)

  1. (İsteğe bağlı.) MFT'nin destekleyebilecekleri en düşük ve en fazla akış sayısını almak içinIMFTransform::GetStreamLimits çağrısı yapın. Minimum ve en yüksek değer aynıysa MFT'nin sabit sayıda akışı vardır.
  2. İlk akış sayısını almak için IMFTransform::GetStreamCount çağrısı yapın.
  3. Akış tanımlayıcılarını almak için IMFTransform::GetStreamIDs çağırın. Bu yöntem E_NOTIMPL döndürürse, MFT'nin sabit sayıda akışı olduğu ve akış tanımlayıcılarının sıfırdan başlayarak ardışık olduğu anlamına gelir.
  4. (İsteğe bağlı.) MFT'de sabit sayıda akış yoksa, daha fazla giriş akışı eklemek için IMFTransform::AddInputStreams veya giriş akışlarını kaldırmak için IMFTransform::D eleteInputStreamçağırın. (Çıkış akışları ekleyemez veya kaldıramazsınız.)

Medya Türlerini Ayarla

MFT'nin verileri işleyebilmesi için önce istemcinin MFT akışlarının her biri için bir medya türü ayarlaması gerekir. MFT, istemcinin çıkış türlerini ayarlamadan önce giriş türlerini ayarlamasını veya karşı sırayı (önce çıkış türleri) gerektirebilir. Bazı MFT'lerde sıra gereksinimi yoktur.

MFT, bir akış için tercih edilen medya türlerinin listesini sağlayabilir. Ayrıca, MFT'ler bu bilgileri kayıt defterine ekleyerek destekledikleri genel biçimleri gösterebilir.

Medya türlerini ayarlamak için aşağıdakileri yapın:

  1. (İsteğe bağlı.) Her giriş akışı için IMFTransform::GetInputAvailableType çağırarak bu akış için tercih edilen türlerin listesini alın.
    • Bu yöntem MF_E_TRANSFORM_TYPE_NOT_SET döndürürse, önce çıkış türlerini ayarlamanız gerekir; 3. adıma atlayın.
    • yöntemi E_NOTIMPL döndürürse, MFT'nin tercih edilen giriş türlerinin listesi yoktur; 2. adıma atlayın.
  2. Her giriş akışı için IMFTransform::SetInputType çağırarak giriş türünü ayarlayın. 1. adımdaki bir medya türünü veya giriş verilerinizi açıklayan bir tür kullanabilirsiniz. Herhangi bir akış MF_E_TRANSFORM_TYPE_NOT_SET döndürüyorsa 3. adıma geçin.
  3. (İsteğe bağlı.) Her çıkış akışı için IMFTransform::GetOutputAvailableType çağırarak bu akış için tercih edilen türlerin listesini alın.
    • Bu yöntem MF_E_TRANSFORM_TYPE_NOT_SET döndürürse, önce giriş türlerini ayarlamanız gerekir; 1. adıma geri dönün.
    • Herhangi bir akış E_NOTIMPL döndürürse, MFT'nin tercih edilen çıkış türlerinin listesi yoktur; 4. adıma atlayın.
  4. Çıkış türünü ayarlamak için her çıkış akışı için IMFTransform::SetOutputType çağırın. 3. adımdaki bir medya türünü veya gerekli çıkış biçiminizi açıklayan bir tür kullanabilirsiniz.
  5. Herhangi bir giriş akışının medya türü yoksa 1. adıma geri dönün.

Arabellek Gereksinimlerini Alma

İstemci medya türlerini ayarlarken, akış başına arabellek gereksinimlerini edinmelidir:

Verileri İşleme

MFT, güvenilir bir durum makinesi olacak şekilde tasarlanmıştır. İstemciye geri çağrı yapmaz.

  1. IMFTransform::ProcessMessageMFT_MESSAGE_NOTIFY_BEGIN_STREAMING iletisiyle çağırın. Bu ileti, MFT'den akış sırasında ihtiyaç duyduğu tüm kaynakları ayırmasını istiyor.
  2. MFT'ye bir giriş örneği teslim etmek için en az bir giriş akışında IMFTransform::P rocessInput çağırın.
  3. (İsteğe bağlı.) MFT'nin bir çıkış örneği oluşturup oluşturamayacağını sorgulamak için IMFTransform::GetOutputStatus çağrısı yapın. Yöntem S_OK döndürürse pdwFlags parametresini denetleyin. pdwFlags değişkeni MFT_OUTPUT_STATUS_SAMPLE_READY bayrağını içeriyorsa, 4. adıma gidin. pdwFlags sıfırsa, 2. adıma geri dönün. Yöntem E_NOTIMPL döndürürse 4. adıma gidin.
  4. Çıkış verilerini almak için IMFTransform::P rocessOutput çağrısı yapın.
    • yöntemi MF_E_TRANSFORM_NEED_MORE_INPUTdöndürürse, MFT daha fazla giriş verisi gerektirir; 2. adıma geri dönün.
    • yöntemi MF_E_TRANSFORM_STREAM_CHANGEdöndürürse, çıkış akışlarının sayısı değişmiş veya çıkış biçimi değişmiş demektir. İstemcinin yeni akış tanımlayıcılarını sorgulaması veya yeni medya türleri ayarlaması gerekebilir. Daha fazla bilgi için ProcessOutputbelgelerine bakın.
  5. İşlenmek üzere hala giriş verileri varsa 2. adıma gidin. MFT tüm kullanılabilir giriş verilerini tüketmişse 6. adıma geçin.
  6. MFT_MESSAGE_NOTIFY_END_OF_STREAM iletisiyle ProcessMessage çağırın.
  7. Çağırın ProcessMessage ile MFT_MESSAGE_COMMAND_DRAIN iletisini.
  8. Kalan çıkışı almak için ProcessOutput çağırın. yöntemi MF_E_TRANSFORM_NEED_MORE_INPUTdöndürene kadar bu adımı yineleyin. Bu dönüş değeri, tüm çıkışın MFT'den çıkartıldığını işaret eder. (Bunu bir hata koşulu olarak değerlendirmeyin.)

Burada açıklanan dizi MFT'de mümkün olduğunca az veri tutar. ProcessInputyapılan her çağrıdan sonra istemci çıkış almayı dener. Bir çıkış örneği oluşturmak için birkaç giriş örneği gerekebilir veya tek bir giriş örneği birkaç çıkış örneği oluşturabilir. İstemci için en uygun davranış, MFT'nin daha fazla giriş talep ettiği ana kadar MFT'den çıkış örnekleri almaktır.

Ancak MFT, istemci tarafından yöntem çağrıları sırasını farklı bir şekilde işleyebilmelidir. Örneğin, istemci yalnızca ProcessInput ve ProcessOutputçağrıları arasında geçiş yapabilir. MFT, üretecek bir çıktısı olduğunda ProcessInput'dan MF_E_NOTACCEPTING döndürerek aldığı giriş miktarını kısıtlamalıdır.

Burada açıklanan yöntem çağrılarının sırası, tek geçerli olay dizisi değildir. Örneğin, 3. ve 4. adımlarda istemcinin giriş türleriyle başladığını ve ardından çıkış türlerini denediğini varsayalım. İstemci ayrıca bu sırayı tersine çevirebilir ve çıkış türleriyle başlayabilir. Her iki durumda da MFT ters sıra gerektiriyorsa hata kodunu MF_E_TRANSFORM_TYPE_NOT_SET döndürmelidir.

İstemci, akış sırasında herhangi bir zamanda GetInputCurrentType ve GetOutputStreamInfogibi bilgilendirici yöntemleri çağırabilir. İstemci, istediğiniz zaman medya türlerini değiştirmeyi de deneyebilir. Bu geçerli bir işlem değilse MFT bir hata kodu döndürmelidir. Kısacası MFT'ler, çağrıların kendilerinde belgelenenler dışında işlemlerin sırası hakkında çok az şey varsaymalıdır.

Aşağıdaki diyagramda, bu konuda açıklanan yordamların akış grafiği gösterilmektedir.

Akış tanımlayıcılarını almaktan başlayarak, giriş türlerini ayarlayan ve giriş alıp çıkışı işleyen döngüler üzerinden ilerleyen akış şeması.

Temel Modelin Uzantıları

İsteğe bağlı olarak, MFT temel akış modelinin bazı uzantılarını destekleyebilir.

  • Yavaş okunan akışlar. IMFTransform::GetOutputStreamInfo yöntemi bir çıkış akışı için MFT_OUTPUT_STREAM_LAZY_READ bayrağını döndürürse, istemcinin bu çıkış akışından veri toplaması gerekmez. MFT girişi kabul etmeye devam eder ve bir noktada MFT bu akıştan çıkış verilerini atar. Tüm çıkış akışlarında bu bayrak varsa MFT hiçbir zaman girişi kabul etmez. Örneğin, bir görselleştirme dönüşümü, istemcinin yalnızca görselleştirmeyi çizmek için yedek CPU döngülerine sahip olduğunda çıktıyı aldığı bir durumu ifade edebilir.
  • Atılabilir akışlar. GetOutputStreamInfo yöntemi bir çıkış akışı için MFT_OUTPUT_STREAM_DISCARDABLE bayrağını döndürürse, istemci MFT'nin çıkışı atması için istekte bulunabilir, ancak MFT istenmediği sürece herhangi bir çıkışı atmayacak. MFT en yüksek giriş arabelleğine ulaştığında istemcinin bazı çıkış verileri toplaması veya MFT'nin çıkışı atması için istekte bulunması gerekir.
  • İsteğe bağlı akışlar. GetOutputStreamInfo yöntemi bir çıkış akışı için MFT_OUTPUT_STREAM_OPTIONAL bayrağını döndürürse veya IMFTransform::GetInputStreamInfo yöntemi giriş akışı için MFT_INPUT_STREAM_OPTIONAL bayrağını döndürürse, bu akış isteğe bağlıdır. İstemcinin akışta bir medya türü ayarlaması gerekmez. İstemci türü ayarlamazsa akış devre dışı bırakılır. Seçili olmayan bir çıkış akışı örnek oluşturmaz ve istemci ProcessOutputçağırdığında akış için bir arabellek sağlamaz. Seçili olmayan giriş akışı giriş verilerini kabul etmez. MFT tüm giriş ve çıkış akışlarını isteğe bağlı olarak işaretleyebilir. Ancak MFT'nin çalışması için en az bir girişin ve bir çıkışın seçilmesi beklenir.
  • Eşzamansız işleme. Zaman uyumsuz işleme modeli Windows 7'de kullanıma sunulmuştur. Konusu Asenkron MFT'leriçinde açıklanmıştır.

IMF2DBuffer

MFT sıkıştırılmamış video verilerini işlerse örnek arabellekleri işlemek için IMF2DBuffer arabirimini kullanmalıdır. Bu arabirimi almak için, herhangi bir giriş veya çıkış arabelleğinde IMFMediaBuffer arabirimini sorgulayın. Bu arabirim kullanılabilir durumdayken kullanılmazsa ek arabellek kopyalarına neden olabilir. Bu arabirimin düzgün bir şekilde kullanılması için dönüştürme, IMF2DBuffer kullanılabilir olduğunda IMFMediaBuffer arabirimini kullanarak arabelleği kilitlememelidir.

Video verilerini işleme hakkında daha fazla bilgi için bkz. Sıkıştırılmamış Video Arabellekleri.

MFT'yi temizleme

Bir MFT'yi Boşaltmak, MFT'nin tüm giriş verilerini atmasına neden olur. Bu, çıkış akışında bir kesmeye neden olabilir. İstemci genellikle veri kaybıyla ilgilenmediğinde giriş akışında yeni bir noktaya geçmeden veya yeni bir giriş akışına geçmeden önce MFT'yi temizler.

MFT'yi temizlemek için MFT_MESSAGE_COMMAND_FLUSH iletisiyle IMFTransform::ProcessMessage çağırın.

Bir MFT'yi boşaltmak

Bir MFT'yi boşaltmak, MFT'nin zaten gönderilmiş olan giriş verilerinden olabildiğince çok çıkış üretmesine neden olur. MFT, kullanılabilir girişten eksiksiz bir çıkış örneği oluşturamazsa, giriş verilerini bırakır. İstemci genellikle kaynak akışın sonuna ulaştığında veya kaynak akıştaki bir biçim değişikliğinden hemen önce MFT'yi boşaltırdı. MFT'yi boşaltmak için aşağıdakileri yapın:

  1. ProcessMessageMFT_MESSAGE_COMMAND_DRAIN mesajı ile çağırın. Bu ileti, MFT'ye zaten gönderilmiş olan giriş verilerinden olabildiğince çok çıktı verisi teslim etmesi gerektiğini bildirir.
  2. Yöntem MF_E_TRANSFORM_NEED_MORE_INPUTdöndürene kadar çıkış verilerini almak için ProcessOutput çağırın.

MFT boşaltılırken, daha fazla veri kabul etmeyecektir.

Örnek Öznitelikler

Giriş örneklerinde ilgili çıkış örneklerine kopyalanması gereken öznitelikler olabilir.

Bir girişi ve bir çıkışı olan bir MFT için aşağıdaki genel kuralı kullanabilirsiniz:

  • Her giriş örneği tam olarak bir çıkış örneği oluşturuyorsa, istemcinin öznitelikleri kopyalamasına izin vekleyebilirsiniz. MFPKEY_EXATTRIBUTE_SUPPORTED özelliğini ayarlamadan bırakın.
  • Giriş örnekleri ile çıkış örnekleri arasında bire bir yazışma yoksa, MFT'nin çıkış örnekleri için doğru öznitelikleri belirlemesi gerekir. MFPKEY_EXATTRIBUTE_SUPPORTED özelliğini VARIANT_TRUEolarak ayarlayın.

Kesintiler

Kesinti, ses veya video akışındaki bir kesintidir. Kesintiler, ağ bağlantısında bırakılan paketler, bozuk dosya verileri, bir kaynak akıştan diğerine geçiş veya çok çeşitli başka nedenlerden kaynaklanabilir. Kesintiler, kesintiden sonraki ilk örnekte MFSampleExtension_Discontinuity özniteliği ayarlanarak işaretlenir. Bir örneğin ortasında kesinti sinyali vermek mümkün değildir. Bu nedenle, kesintili veriler ayrı örneklerde gönderilmelidir.

Özellikle ses ve video efektleri gibi sıkıştırılmamış verileri işleyen bazı dönüşümler, giriş verilerini işlerken kesintileri yoksamalıdır. Bu MFT'ler genellikle sürekli verileri işlemek için tasarlanmıştır ve kesinti sonrasında bile aldıkları verileri sürekli olarak ele almalıdır.

MFT giriş verilerinde kesintiyi yoksayarsa, çıkış örneğinin giriş örneğiyle aynı zaman damgasına sahip olması durumunda yine de çıkış örneğinde kesinti bayrağını ayarlaması gerekir. Ancak çıkış örneğinde farklı bir zaman damgası varsa, MFT kesintiyi yaymamalıdır. (Örneğin, bazı ses yeniden örnekleyicilerinde bu durum söz konusu olabilir.) Akışta yanlış yerde kesinti olması, kesinti olmamasından daha kötüdür.

Bir kesinti sonraki örneğin yorumlanmasını etkilediğinden çoğu kod çözücü, kesintileri yoksayamaz. MPEG-2 gibi çerçeveler arası sıkıştırma kullanan tüm kodlama teknolojileri bu kategoriye girer. Bazı kodlama düzenleri yalnızca DV ve MJPEG gibi çerçeve içi sıkıştırma kullanır. Bu kod çözücüler, kesintileri güvenle göz ardı edebilir.

Kesintilere yanıt veren dönüşümler genellikle kesintiden önce olabildiğince çok veri çıkışı yapmalı ve geri kalanını atmalıdır. Kesinti bayrağına sahip giriş örneği, akıştaki ilk örnekmiş gibi işlenmelidir. (Bu davranış, MFT_MESSAGE_COMMAND_DRAIN iletisi için belirtilenle eşleşir.) Ancak, tam ayrıntılar medya biçimine bağlıdır.

Bir kod çözücü bir kesintiyi azaltmak için hiçbir şey yapmazsa, kesinti işaretini çıkış verilerine kopyalaması gerekir. Tamamen sıkıştırılmış verilerle çalışan demultipleksörler veya diğer MFT'ler, çıkış akışlarına kesintileri kopyalamalıdır. Aksi takdirde, aşağı akış bileşenleri sıkıştırılmış verilerin kodunu doğru şekilde çözemeyebilir. Genel olarak, MFT kesintileri düzeltmek için açık kod içermediği sürece kesintileri aşağı akışa geçirmek neredeyse her zaman doğrudur.

Dinamik Biçim Değişiklikleri

Akış sırasında biçimler değişebilir. Örneğin, video akışının ortasında en boy oranı değişebilir.

Akış değişikliklerinin bir MFT tarafından nasıl işleneceğinin ayrıntıları için bkz. Akış Değişikliklerini İşleme.

Akış Olayları

MFT'ye olay göndermek için IMFTransform::P rocessEventçağrısı yapın. Yöntem MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENTdeğerini döndürürse, MFT, ProcessOutputadlı sonraki bir çağrıda olayı çağırana geri döndürecektir. Başka bir HRESULT değeri döndüğü takdirde, MFT olayını ProcessOutputiçinde istemciye döndürmeyecektir. Bu durumda istemci, olayı, varsa, işlem hattındaki bir sonraki bileşene doğru yaymakla sorumludur. Daha fazla bilgi için bkz. IMFTransform::P rocessOutput.

Media Foundation Dönüşümleri