Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен на MediaPlayer, IMFMediaEngineи Аудио/видеозахват в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует в новом коде использовать MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation по возможности вместо DirectShow. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
Когда MPEG-2 demux поставляет полезные данные PES, он отправляет поток байтов ES в пакетах образцов мультимедиа. Размер выборки по умолчанию — 8 КБ. Demux запускает новый медиаобразец на каждом рубеже PES-сегмента, но может разбить один пакет данных PES на несколько образцов. Например, если полезные данные PES равны 20K, они будут доставлены в двух частях по 8K, затем одна часть 4K. Демукс не проверяет содержимое потока байтов. На декодатор возлагается задача разбирать заголовки последовательности и отслеживать изменения формата.
Когда выходной контакт фильтра демультиплексирования подключается к декодеру, он предоставляет тип носителя, указанный при создании контакта. Так как demux не проверяет поток байтов ES, он не проверяет тип носителя. В теории декодатор MPEG-2 должен иметь возможность подключиться, указав только основной тип и подтип, чтобы обозначить тип данных. Декодатор должен затем проверить заголовки последовательности, поступающие в образцы мультимедиа. Однако на практике многие декодеры не подключаются, если тип носителя не включает полный блок формата.
Например, предположим, что PID 0x31 содержит видео в основном профиле MPEG-2. Как минимум, вам потребуется выполнить следующие действия.
Сначала создайте тип мультимедиа для видео MPEG-2. Отложим блок форматирования в сторону на данный момент.
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video ;
mt.subtype = MEDIASUBTYPE_MPEG2_VIDEO;
// Possibly create a format block (not shown here).
Затем создайте выходной пин-код в демуксе:
// Query the demux filter for IMpeg2Demultiplexer.
IMpeg2Demultiplexer *pDemux;
hr = pFilter->QueryInterface(IID_IMpeg2Demultiplexer, (void**)&pDemux);
if (SUCCEEDED(hr))
{
// Create a new output pin.
IPin *pPin0;
hr = pDemux->CreateOutputPin(&mt, L"Video Pin", &pPin0);
if (SUCCEEDED(hr))
{
....
}
}
Затем запросите новый пин-код для интерфейса IMPEG2PIDMap и вызовите MapPID. Укажите номер PID 0x30 и MEDIA_ELEMENTARY_STREAM для полезных данных PES.
// Query the pin for IMPEG2PIDMap. This implicitly configures the
// demux to carry a transport stream.
IMPEG2PIDMap *pPidMap;
hr = pPin0->QueryInterface(IID_IMPEG2PIDMap, (void**)&pPidMap);
if (SUCCEEDED(hr))
{
// Assign PID 0x31 to pin 0. Set the type to "PES payload."
ULONG Pid = 0x031;
hr = pPidMap->MapPID(1, &Pid, MEDIA_ELEMENTARY_STREAM);
pPidMap->Release();
}
Наконец, освободите все интерфейсы после завершения работы.
pPin0->Release();
pDemux->Release();
Ниже приведен более полный пример настройки типа носителя, включая блок формата. В этом примере по-прежнему предполагается видео основного профиля MPEG-2. Сведения будут отличаться в зависимости от содержимого потока:
// Set up a byte array to hold the first sequence header.
// This may or may not be required, depending on the decoder.
BYTE SeqHdr[] = { ... }; // Contains the sequence header (not shown).
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video ;
mt.subtype = MEDIASUBTYPE_MPEG2_VIDEO;
mt.formattype = FORMAT_MPEG2Video;
// Allocate the format block, including space for the sequence header.
mt.cbFormat = sizeof(MPEG2VIDEOINFO) + sizeof(SeqHdr);
mt.pbFormat = (BYTE*)CoTaskMemAlloc(mt.cbFormat);
if (mt.pbFormat == NULL)
{
// Out of memory; return an error code.
}
ZeroMemory(mt.pbFormat, mt.cbFormat);
// Cast the buffer pointer to an MPEG2VIDEOINFO struct.
MPEG2VIDEOINFO *pMVIH = (MPEG2VIDEOINFO*)mt.pbFormat;
RECT rcSrc = {0, 480, 0, 720}; // Source rectangle.
pMVIH->hdr.rcSource = rcSrc;
pMVIH->hdr.dwBitRate = 4000000; // Bit rate.
pMVIH->hdr.AvgTimePerFrame = 333667; // 29.97 fps.
pMVIH->hdr.dwPictAspectRatioX = 4; // 4:3 aspect ratio.
pMVIH->hdr.dwPictAspectRatioY = 3;
// BITMAPINFOHEADER information.
pMVIH->hdr.bmiHeader.biSize = 40;
pMVIH->hdr.bmiHeader.biWidth = 720;
pMVIH->hdr.bmiHeader.biHeight = 480;
pMVIH->dwLevel = AM_MPEG2Profile_Main; // MPEG-2 profile.
pMVIH->dwProfile = AM_MPEG2Level_Main; // MPEG-2 level.
// Copy the sequence header into the format block.
pMVIH->cbSequenceHeader = sizeof(SeqHdr); // Size of sequence header.
memcpy(pMVIH->dwSequenceHeader, SeqHdr, sizeof(SeqHdr));
Связанные разделы