Написание проекта в файл
[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен на MediaPlayer, IMFMediaEngineи захват аудио и видео в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый код с применением MediaPlayer, IMFMediaEngine и средств захвата аудио и видео в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
[Этот API не поддерживается и может быть изменен или недоступен в будущем.]
В этой статье описывается, как записать проект Службы редактирования DirectShow в файл. Сначала он описывает, как написать файл с помощью базового обработчика отрисовки. Затем он описывает умное повторное сжатие с помощью умного движка построения.
Общие сведения о том, как службы редактирования DirectShow отрисовывает проекты, см. в разделе о модулях отрисовки.
Использование базового рендер-движка
Начните с создания передней части графа, как показано ниже.
- Создайте обработчик отрисовки.
- Укажите временную шкалу.
- Задайте диапазон отрисовки. (Необязательно)
- Создайте внешний интерфейс графа.
В следующем примере кода показаны эти действия.
IRenderEngine *pRender = NULL;
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC,
IID_IRenderEngine, (void**) &pRender);
hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );
Затем добавьте мультиплексер и фильтры записи файлов в граф фильтров. Самый простой способ сделать это — с помощью Capture Graph Builder, компонента DirectShow для построения графов захвата. Построитель графов захвата предоставляет интерфейс ICaptureGraphBuilder2. Выполните следующие действия.
- Создайте экземпляр построителя графов захвата.
- Получите указатель на граф и передайте его в построитель графов.
- Укажите имя и тип носителя выходного файла. Этот шаг также получает указатель на мультиплексорный фильтр, который потребуется позже.
В следующем примере кода показаны эти действия.
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **)&pBuilder);
// Get a pointer to the graph front end.
IGraphBuilder *pGraph;
pRender->GetFilterGraph(&pGraph);
pBuilder->SetFiltergraph(pGraph);
// Create the file-writing section.
IBaseFilter *pMux;
pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,
OLESTR("Output.avi"), &pMux, NULL);
Наконец, подключите выходные выводы на передней панели к мультиплексному фильтру.
- Получение количества групп.
- Для каждого пина получите указатель на пин.
- При необходимости создайте экземпляр фильтра сжатия для сжатия потока. Тип компрессора будет зависеть от типа средств массовой информации группы. Для перечисления доступных фильтров сжатия можно использовать перечислителя системных устройств. Дополнительные сведения см. в разделе Перечисление устройств и фильтров.
- При необходимости задайте параметры сжатия, такие как частота ключевых кадров. Этот шаг подробно рассматривается далее в статье.
- Вызов ICaptureGraphBuilder2::RenderStream. Этот метод принимает указатели на пин, фильтр сжатия (если таковой имеется) и мультиплексор.
В следующем примере кода показано, как подключить выходы.
long NumGroups;
pTimeline->GetGroupCount(&NumGroups);
// Loop through the groups and get the output pins.
for (i = 0; i < NumGroups; i++)
{
IPin *pPin;
if (pRender->GetGroupOutputPin(i, &pPin) == S_OK)
{
IBaseFilter *pCompressor;
// Create a compressor filter. (Not shown.)
// Set compression parameters. (Not shown.)
// Connect the pin.
pBuilder->RenderStream(NULL, NULL, pPin, pCompressor, pMux);
pCompressor->Release();
pPin->Release();
}
}
Чтобы задать параметры сжатия (шаг 4, ранее), используйте интерфейс IAMVideoCompression. Этот интерфейс присутствует на выводах фильтров компрессии. Перечислить пины фильтра сжатия и запросить каждый выходной пин для IAMVideoCompression. (Сведения о перечислении контактов см. в разделе Перечисление контактов.) Убедитесь, что освободили все указатели интерфейса, полученные на этом шаге.
После сборки графа фильтра вызовите метод IMediaControl::Run в диспетчере графов фильтров. По мере запуска графа фильтра данные записываются в файл. Используйте уведомление о событии, чтобы дождаться завершения воспроизведения. (См. Ответ на события.) После завершения воспроизведения необходимо явно вызвать IMediaControl::Stop, чтобы остановить график фильтров. В противном случае файл написан неправильно.
Использование смарт-рендеринга
Чтобы получить преимущества интеллектуального повторного сжатия, используйте интеллектуальный модуль отрисовки вместо базового обработчика отрисовки. Действия по созданию графа почти одинаковы. Основное различие заключается в том, что сжатие обрабатывается в передней части графа, а не в разделе записи файлов.
Важный
Не используйте модуль интеллектуальной отрисовки для чтения или записи файлов Windows Media.
Каждая группа видео имеет свойство, указывающее формат сжатия для этой группы. Формат сжатия должен точно соответствовать несжатому формату группы по высоте, ширине, битовой глубине и частоте кадров. Модуль интеллектуальной отрисовки использует формат сжатия при создании графа. Перед настройкой формата сжатия необходимо задать несжатый формат для этой группы путем вызова IAMTimelineGroup::SetMediaType.
Чтобы задать формат сжатия группы, вызовите метод IAMTimelineGroup::SetSmartRecompressFormat. Этот метод принимает указатель на структуру SCompFmt0. Структура SCompFmt0 состоит из двух членов: nFormatId, которые должны быть нулевыми, и MediaType, которая является структурой AM_MEDIA_TYPE. Инициализировать структуру AM_MEDIA_TYPE с сведениями о формате.
Заметка
Если окончательный проект должен иметь тот же формат, что и один из исходных файлов, вы можете получить структуру AM_MEDIA_TYPE непосредственно из исходного файла с помощью детектора мультимедиа. См. раздел IMediaDet::get_StreamMediaType.
Приведите переменнуютипаSCompFmt0 к указателю типа long, как показано в следующем примере.
SCompFmt0 *pFormat = new SCompFmt0;
memset(pFormat, 0, sizeof(SCompFmt0));
pFormat->nFormatId = 0;
// Initialize pFormat->MediaType. (Not shown.)
pGroup->SetSmartRecompressFormat( (long*) pFormat );
Модуль интеллектуальной отрисовки автоматически ищет совместимый фильтр сжатия. Кроме того, можно указать фильтр сжатия для группы, вызвав ISmartRenderEngine::SetGroupCompressor.
Чтобы создать граф, используйте те же шаги, которые были описаны для базового рендер-движка в предыдущем разделе. Единственными отличиями являются следующие:
- Используйте интеллектуальный модуль отрисовки, а не базовый обработчик отрисовки. Идентификатор класса CLSID_SmartRenderEngine.
- Задайте параметры сжатия после сборки фронт-энда, но перед отображением выходных выводов. Вызовите метод ISmartRenderEngine::GetGroupCompressor, чтобы получить указатель на фильтр сжатия группы. Затем запросите интерфейс IAMVideoCompression, как описано ранее.
- При отрисовке выходных контактов не требуется вставлять фильтр сжатия. Поток уже сжимается.
Связанные разделы