Настройка свойств сжатия видео
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
Фильтры сжатия видео могут поддерживать интерфейс IAMVideoCompression на выходных контактах. Используйте этот интерфейс для задания свойств сжатия, таких как частота ключевых кадров, число прогнозируемых (P) кадров на ключевой кадр и относительное качество сжатия.
Сначала вызовите метод IBaseFilter::EnumPins , чтобы найти выходной контакт фильтра и запросить контакт для интерфейса. Некоторые фильтры могут вообще не поддерживать интерфейс. Другие могут предоставлять интерфейс, но не поддерживают все свойства сжатия. Чтобы определить, какие свойства поддерживаются, вызовите IAMVideoCompression::GetInfo. Этот метод возвращает несколько фрагментов информации:
- Набор флагов возможностей
- Описательная строка и строка номера версии
- Значения по умолчанию для ключевой частоты кадров, частоты кадров P и качества (если это поддерживается)
Метод имеет следующий синтаксис:
hr = pCompress->GetInfo(pszVersion, &cbVersion, pszDesc, &cbDesc,
&lKeyFrame, &lPFrame, &dblQuality, &lCap);
Параметры pszVersion и pszDesc — это буферы расширенных символов, которые получают строку версии и строку описания. Параметры cbVersion и cbDesc получают требуемые размеры буфера в байтах (не символах). Параметры lKeyFrame, lPFrame и dblQuality получают значения по умолчанию для ключевой частоты кадров, частоты кадров P и качества. Качество выражается в виде числа с плавающей запятой от 0,0 до 1,0. Параметр lCap получает побитовое ИЛИ флагов возможностей, которые определяются перечисленным типом CompressionCaps .
Любой из этих параметров может иметь значение NULL, и в этом случае метод игнорирует этот параметр. Например, чтобы выделить буферы для строк версии и описания, сначала вызовите метод со значением NULL в первом и третьем параметрах. Используйте возвращаемые значения для cbVersion и cbDesc , чтобы выделить буферы, а затем снова вызовите метод :
int cbVersion, cbDesc; // Size in bytes, not characters!
hr = pCompress->GetInfo(0, &cbVersion, 0, &cbDesc, 0, 0, 0, 0);
if (SUCCEEDED(hr))
{
WCHAR *pszVersion = new WCHAR[cbVersion/2]; // Wide character = 2 bytes
WCHAR *pszDesc = new WCHAR[cbDesc/2];
hr = pCompress->GetInfo(pszVersion, 0, pszDesc, 0, 0, 0, 0, 0);
}
Значение lCap указывает, какой из других методов IAMVideoCompression поддерживает фильтр. Например, если lCap содержит флаг CompressionCaps_CanKeyFrame, можно вызвать IAMVideoCompression::get_KeyFrameRate для получения ключевой частоты кадров и IAMVideoCompression::p ut_KeyFrameRate , чтобы задать частоту кадров. Отрицательное значение указывает, что фильтр будет использовать значение по умолчанию, полученное из IAMVideoCompression::GetInfo. Пример:
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
{
lKeyFrame = lDefaultKeyFrame; // From GetInfo.
}
}
В следующем примере кода пытается найти интерфейс IAMVideoCompression в выходном контакте. В случае успешного выполнения извлекаются значения по умолчанию и фактические значения для свойств сжатия:
HRESULT hr = E_FAIL;
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
IAMVideoCompression *pCompress = NULL;
// Find the pin that supports IAMVideoCompression (if any).
pFilter->EnumPins(&pEnum);
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
hr = pPin->QueryInterface(IID_IAMVideoCompression, (void**)&pCompress);
pPin->Release();
if (SUCCEEDED(hr)) // Found the interface.
{
break;
}
}
if (SUCCEEDED(hr))
{
long lCap; // Capability flags
long lKeyFrame, lPFrame; // Real values
double m_Quality;
long lKeyFrameDef, lPFrameDef; // Default values
double QualityDef;
// Get default values and capabilities.
hr = pCompress->GetInfo(0, 0, 0, 0, &KeyFrameDef, &lPFrameDef,
&QualityDef, &lCap);
if (SUCCEEDED(hr))
{
// Get actual values where possible.
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
lKeyFrame = lKeyFrameDef;
}
if (lCap & CompressionCaps_CanBFrame)
{
hr = pCompress->get_PFramesPerKeyFrame(&lPFrame);
if (FAILED(hr) || lPFrame < 0)
lPFrame = lPFrameDef;
}
if (lCap & CompressionCaps_CanQuality)
{
hr = pCompress->get_Quality(&Quality);
if (FAILED(hr) || Quality < 0)
Quality = QualityDef;
}
}
}
Примечание
Если для построения графа используется интерфейс ICaptureGraphBuilder2 , интерфейс IAMVideoCompression можно получить, вызвав ICaptureGraphBuilder2::FindInterface вместо использования IBaseFilter::EnumPins. Метод FindInterface — это вспомогательный метод, который выполняет поиск указанного интерфейса в фильтрах и закреплениях на графе.