Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Windows Media Video (WMV) kodlayıcı için geçerli bir çıkış türü oluşturmak için aşağıdaki bilgilere sahip olmanız gerekir:
- Kodladığınız sıkıştırılmamış videonun biçimi.
- Kodlanmış WMV biçimini tekrarlayan video alt türü. Bkz. Video Alt Tür GUID'leri.
- Kodlanmış akışın hedef bit hızı.
- Kodlayıcıda ayarlanacağı yapılandırma özellikleri.
Yapılandırma özellikleri Windows Media Ses ve Video Codec'i ve DSP API'leri belgelerinde belgelenmiştir. Daha fazla bilgi için bkz. Kodlama Özellikleri"Video Akışı Özellikleri".
Kodlayıcı için geçerli bir çıkış türü almak için aşağıdaki adımları gerçekleştirin.
Kodlayıcının bir örneğini oluşturmak için MFTEnum veya MFTEnumEx işlevini kullanın.
IPropertyStore arabirimi için kodlayıcıyı sorgula.
Kodlayıcıyı yapılandırmak için IPropertyStore arabirimini kullanın.
Kodlayıcıda sıkıştırılmamış video türünü ayarlamak için IMFTransform::SetInputType çağrısı yapın.
Kodlayıcıdan sıkıştırma biçimlerinin listesini almak için IMFTransform::GetOutputAvailableTypeçağırın. WMV kodlayıcıları bu yöntemden tam bir medya türü döndürmez. Medya türlerinde iki bilgi eksik:
- Hedef bit hızı.
- Kodlayıcıdan özel codec verileri.
Kodlayıcıda çıkış türünü ayarlamadan önce, bu öğelerin her ikisini de medya türüne eklemeniz gerekir.
Hedef bit hızını belirtmek için medya türünde MF_MT_AVG_BITRATE özniteliğini ayarlayın.
Sonraki bölümde açıklandığı gibi özel codec verilerini medya türüne ekleyin.
Kodlayıcıda sıkıştırma medya türünü ayarlamak için IMFTransform::SetOutputType çağırın.
Özel Codec Verileri
Özel codec verileri, WMV kodlayıcıdan almanız ve kodlayıcıda sıkıştırma türünü ayarlamadan önce sıkıştırma türüne eklemeniz gereken opak bir veri yapısıdır. Özel verileri almak için Windows Media Format 11 SDK'sında belgelenen IWMCodecPrivateData arabirimini kullanmanız gerekir.
Özel codec verilerini almak için aşağıdaki adımları uygulayın:
- Kodlayıcıdan bir medya türü almak için IMFTransform::GetOutputAvailableType çağırın. (Bu, önceki bölümdeki 6. adımdır.)
- Medya türündeki MF_MT_AVG_BITRATE özniteliğini ayarlayarak hedef bit hızını belirtin.
- Medya türünü, MFInitAMMediaTypeFromMFMediaType işlevini çağırarak, DMO_MEDIA_TYPE yapısına dönüştürün.
- IWMCodecPrivateData arabirimi için kodlayıcıyı sorgular.
- Dönüştürülen DMO_MEDIA_TYPE yapısını geçirerek IWMCodecPrivateData::SetPartialOutputType yöntemini çağırın.
- IWMCodecPrivateData::GetPrivateData yöntemini iki kez, bir kez özel verilerin arabelleğinin boyutunu almak ve bir kez de verileri arabelleğe kopyalamak için çağırın.
- Türdeki MF_MT_USER_DATA özniteliğini ayarlayarak özel verileri medya türüne ekleyin.
Aşağıdaki genişletilmiş örnek, sıkıştırılmamış bir video türünden WMV sıkıştırma biçiminin nasıl oluşturulacağını gösterir:
#include <wmcodecdsp.h>
#include <Wmsdk.h>
#include <Dmo.h>
#include <mfapi.h>
#include <uuids.h>
#include <mfidl.h>
#include <mftransform.h>
#include <mferror.h>
#pragma comment(lib, "Msdmo")
#pragma comment(lib, "mfplat")
#pragma comment(lib, "mfuuid")
#pragma comment(lib, "strmiids")
#pragma comment(lib, "propsys")
HRESULT GetEncodedVideoType(
IMFMediaType *pTypeIn,
REFGUID subtype,
UINT32 TargetBitrate,
IPropertyStore *pEncoderProps,
IMFMediaType **ppEncodingType,
DWORD mftEnumFlags = MFT_ENUM_FLAG_SYNCMFT
);
HRESULT CreateVideoEncoder(REFGUID subtype, DWORD mftEnumFlags, IMFTransform **ppMFT);
HRESULT AddPrivateData(IMFTransform *pMFT, IMFMediaType *pTypeOut);
HRESULT CopyPropertyStore(IPropertyStore *pSrc, IPropertyStore *pDest);
//
// GetEncodedVideoType
// Given an uncompressed video type, finds a suitable WMV type.
//
HRESULT GetEncodedVideoType(
IMFMediaType *pTypeIn, // Uncompressed format
REFGUID subtype, // Compression format
UINT32 TargetBitrate, // Target bit rate
IPropertyStore *pEncoderProps, // Encoder properties (can be NULL)
IMFMediaType **ppEncodingType, // Receives the WMV type.
DWORD mftEnumFlags // MFTEnumEx flags
)
{
HRESULT hr = S_OK;
IMFTransform *pMFT = NULL;
IPropertyStore *pPropStore = NULL;
IMFMediaType *pTypeOut = NULL;
// Instantiate the encoder
hr = CreateVideoEncoder(subtype, mftEnumFlags, &pMFT);
// Copy the properties to the encoder.
if (SUCCEEDED(hr))
{
if (pEncoderProps)
{
hr = pMFT->QueryInterface(IID_PPV_ARGS(&pPropStore));
if (SUCCEEDED(hr))
{
hr = CopyPropertyStore(pEncoderProps, pPropStore);
}
}
}
// Set the uncompressed type.
if (SUCCEEDED(hr))
{
hr = pMFT->SetInputType(0, pTypeIn, 0);
}
// Get the partial output type
if (SUCCEEDED(hr))
{
hr = pMFT->GetOutputAvailableType(0, 0, &pTypeOut);
}
// Set the bit rate.
// You must set this before getting the codec private data.
if (SUCCEEDED(hr))
{
hr = pTypeOut->SetUINT32(MF_MT_AVG_BITRATE, TargetBitrate);
}
if (SUCCEEDED(hr))
{
hr = AddPrivateData(pMFT, pTypeOut);
}
if (SUCCEEDED(hr))
{
hr = pMFT->SetOutputType(0, pTypeOut, 0);
}
if (SUCCEEDED(hr))
{
*ppEncodingType = pTypeOut;
(*ppEncodingType)->AddRef();
}
SafeRelease(&pMFT);
SafeRelease(&pPropStore);
SafeRelease(&pTypeOut);
return hr;
}
CreateVideoEncoder işlevi, belirtilen bir video alt türü için MFVideoFormat_WMV3gibi bir video kodlayıcı oluşturur:
//
// CreateVideoEncoder
// Creates a video encoder for a specified video subtype.
//
HRESULT CreateVideoEncoder(
REFGUID subtype, // Encoding subtype.
DWORD mftEnumFlags, // Flags for MFTEnumEx
IMFTransform **ppMFT // Receives a pointer to the encoder.
)
{
HRESULT hr = S_OK;
IMFTransform *pMFT = NULL;
MFT_REGISTER_TYPE_INFO info;
info.guidMajorType = MFMediaType_Video;
info.guidSubtype = subtype;
IMFActivate **ppActivates = NULL;
UINT32 count = 0;
hr = MFTEnumEx(
MFT_CATEGORY_VIDEO_ENCODER,
mftEnumFlags | MFT_ENUM_FLAG_SORTANDFILTER,
NULL,
&info,
&ppActivates,
&count
);
if (count == 0)
{
hr = E_FAIL;
}
if (SUCCEEDED(hr))
{
hr = ppActivates[0]->ActivateObject(
__uuidof(IMFTransform),
(void**)&pMFT
);
}
if (SUCCEEDED(hr))
{
*ppMFT = pMFT;
(*ppMFT)->AddRef();
}
// Clean up
for (DWORD i = 0; i < count; i++)
{
ppActivates[i]->Release();
}
CoTaskMemFree(ppActivates);
SafeRelease(&pMFT);
return hr;
}
AddPrivateData işlevi özel codec verilerini sıkıştırma türüne ekler:
//
// AddPrivateData
// Appends the private codec data to a media type.
//
// pMFT: The video encoder
// pTypeOut: A video type from the encoder's type list.
//
// The function modifies pTypeOut by adding the codec data.
//
HRESULT AddPrivateData(IMFTransform *pMFT, IMFMediaType *pTypeOut)
{
HRESULT hr = S_OK;
ULONG cbData = 0;
BYTE *pData = NULL;
IWMCodecPrivateData *pPrivData = NULL;
DMO_MEDIA_TYPE mtOut = { 0 };
// Convert the type to a DMO type.
hr = MFInitAMMediaTypeFromMFMediaType(
pTypeOut,
FORMAT_VideoInfo,
(AM_MEDIA_TYPE*)&mtOut
);
if (SUCCEEDED(hr))
{
hr = pMFT->QueryInterface(IID_PPV_ARGS(&pPrivData));
}
if (SUCCEEDED(hr))
{
hr = pPrivData->SetPartialOutputType(&mtOut);
}
//
// Get the private codec data
//
// First get the buffer size.
if (SUCCEEDED(hr))
{
hr = pPrivData->GetPrivateData(NULL, &cbData);
}
if (SUCCEEDED(hr))
{
pData = new BYTE[cbData];
if (pData == NULL)
{
hr = E_OUTOFMEMORY;
}
}
// Now get the data.
if (SUCCEEDED(hr))
{
hr = pPrivData->GetPrivateData(pData, &cbData);
}
// Add the data to the media type.
if (SUCCEEDED(hr))
{
hr = pTypeOut->SetBlob(MF_MT_USER_DATA, pData, cbData);
}
delete [] pData;
MoFreeMediaType(&mtOut);
SafeRelease(&pPrivData);
return hr;
}
CopyPropertyStore işlevi, özellikleri bir özellik deposundan diğerine kopyalayan bir yardımcı işlevdir:
//
// CopyPropertyStore
// Helper function to copy properties from one property
// store to another property store.
//
HRESULT CopyPropertyStore(IPropertyStore *pSrc, IPropertyStore *pDest)
{
HRESULT hr = S_OK;
DWORD cProps = 0;
PROPERTYKEY key;
PROPVARIANT var;
PropVariantInit(&var);
hr = pSrc->GetCount(&cProps);
if (SUCCEEDED(hr))
{
for (DWORD i = 0; i < cProps; i++)
{
hr = pSrc->GetAt(i, &key);
if (FAILED(hr)) { break; }
hr = pSrc->GetValue(key, &var);
if (FAILED(hr)) { break; }
hr = pDest->SetValue(key, var);
if (FAILED(hr)) { break; }
PropVariantClear(&var);
}
}
PropVariantClear(&var);
return hr;
}
İlgili konular