Запись проекта в файл
[Функция, связанная с этой страницей 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( );
Затем добавьте мультиплексорные фильтры и фильтры записи файлов в граф фильтров. Самый простой способ сделать это с помощью построителя захвата графов, компонента 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 , как описано выше.
- При отрисовке выходных контактов нет необходимости вставлять фильтр сжатия. Поток уже сжат.
Связанные темы