Кодировщик Windows Media не сохраняет MF_MT_MPEG_SEQUENCE_HEADER - PullRequest
1 голос
/ 29 марта 2019

Я хочу использовать Win7 Media Foundation SDK для кодирования видеокадров в H264, а затем использовать приемник, чтобы сохранить их как файл .mp4.Однако завершение работы приемника не выполняется, когда я не добавляю MF_MT_MPEG_SEQUENCE_HEADER к выходному медиатайпу вручную, и файл не воспроизводится.

Я проверил кодировщик, который должен его добавить (см. H.264 Видеокодер ).Но это просто выдает ошибку MF_E_ATTRIBUTENOTFOUND.

IMFMediaType * outputType;
hr = m_pEncoder->GetOutputCurrentType(0, &outputType);
UINT32 sequenceHeaderDataSize;
hr = outputType->GetBlobSize(MF_MT_MPEG_SEQUENCE_HEADER, &sequenceHeaderDataSize);

С MF_MT_MPEG_SEQUENCE_HEADER, который я нашел в Интернете (для 1080p), я смог получить воспроизводимый файл.Однако он все еще имеет некоторые ошибки в яркости (случайные изменения ~ каждые 0,5 секунды) и ошибки блокировки.

UINT8 blob[] = {0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x2A, 0xAD, 0x84, 0x01, 0x0C, 0x20, 0x08, 0x61, 0x00, 0x43, 0x08, 0x02, 0x18, 0x40, 0x10, 0xC2, 0x00, 0x84, 0x2B, 0x50, 0x3C, 0x01, 0x13, 0xF2, 0xC2, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x79, 0x08, 0x00, 0x00, 0x00, 0x01, 0x68, 0xEE, 0x3C, 0xB0};


//create sink attributes
IMFAttributes *  sinkAttributes = NULL;
HRESULT hr = MFCreateAttributes(&sinkAttributes, 1);
hr = sinkAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, true);

//create sink
IMFSinkWriter * pSinkWriter = NULL;
hr = MFCreateSinkWriterFromURL(L"output.mp4", NULL, sinkAttributes, &pSinkWriter);

// Set the output media type.
IMFMediaType * pMediaTypeOut = NULL;
CHECK_HR(MFCreateMediaType(&pMediaTypeOut));
CHECK_HR(pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
CHECK_HR(pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, VIDEO_INPUT_FORMAT));
CHECK_HR(MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, VIDEO_WIDTH, VIDEO_HEIGHT));
CHECK_HR(MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, VIDEO_FPS, 1));
CHECK_HR(pMediaTypeOut->SetBlob(MF_MT_MPEG_SEQUENCE_HEADER, blob, sizeof(blob)));
CHECK_HR(pSinkWriter->AddStream(pMediaTypeOut, &streamIndex));

// Tell the sink writer to start accepting data.
hr = pSinkWriter->BeginWriting();

Это может быть связано с Windows 7, к сожалению, я не могу проверить на компьютере с Windows 10.

Закодированные кадры нужны где-то еще, поэтому я не могу просто пропуститькодирование и положить мои кадры прямо в раковину.

1 Ответ

1 голос
/ 29 марта 2019

Некоторые кодировщики, такие как, если я правильно помню, довольно популярны и доступны в Windows 7 Intel Quick Sync, делают MF_MT_MPEG_SEQUENCE_HEADER доступным только после начала обработки образца.То есть, когда вы управляете MFT, вы должны выполнить ProcessInput, ProcessOutput, обработать динамическое изменение формата, изменить тип носителя, и в новом типе носителя у вас будет заголовок последовательности.То есть вы должны начинать кодирование и инициализировать модуль записи приемника только тогда, когда вы готовы к данным, полученным от кодера после того, как туда отправляется первоначальный ввод.

У вас должны быть правильные MF_MT_MPEG_SEQUENCE_HEADER, и вы не можете усердно работатькод случайных значений.Вы можете использовать его для устранения неполадок, как и раньше, но это не просто некоторые байты для данного разрешения.

Примечание Обновления Windows 8 для источника и приемника MPEG-4 :

SPS и PPS могут быть извлечены из входных выборок в приемнике MPEG-4.

Когда SPS и PPS не установлены через MF_MT_MPEG_SEQUENCE_HEADER на типе носителя ввода для приемника MPEG-4, приемник MPEG-4 попытаетсяизвлечь SPS и PPS из входных образцов.Приемник MPEG-4 игнорирует любые входные выборки до тех пор, пока не найдет первые SPS и PPS, поскольку все входные выборки без SPS и PPS не могут декодироваться.

Таким образом, в Windows 8 все работает из-заобновления недоступны в Windows 7, и вам придется справиться с MF_MT_MPEG_SEQUENCE_HEADER самостоятельно.

...