Кодировщик Windows Media не сохраняет MF_MT_MPEG_SEQUENCE_HEADER

Я хочу использовать SDK Win7 Media Foundation для кодирования видеокадров в 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.

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
212
1

Ответы 1

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

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

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

SPS and PPS can be extracted from input samples in MPEG-4 sink.

When SPS and PPS are not set through MF_MT_MPEG_SEQUENCE_HEADER on input media type of the MPEG-4 sink, MPEG-4 sink will try to extract SPS and PPS from input samples. MPEG-4 sink ignores any input samples until it finds the first SPS and PPS, because all input samples without SPS and PPS are not decode-able.

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

Действительно, я использую Windows 7 Intel Quick Sync. однако m_pEncoder->ProcessOutput-метод никогда не возвращает MF_E_TRANSFORM_STREAM_CHANGE даже после нескольких кадров. Я также проверяю, был ли добавлен MF_MT_MPEG_SEQUENCE_HEADER позже, но не повезло. Конечно, жесткое кодирование заголовка предназначено только для целей отладки.

ShixX 29.03.2019 11:00

(У меня нет Win7, чтобы проверить) может быть, тогда вы можете извлечь заголовок из полезной нагрузки? Это должно быть довольно просто - использовать первый вывод кодировщика.

Roman R. 29.03.2019 11:48

Заголовок не включается в полезную нагрузку. По крайней мере, вы не можете извлечь его ни из одного из выходов энкодера. У меня была возможность попробовать это на компьютере с Win10, где все работает отлично. Позже я попытаюсь извлечь заголовок на компьютере с Win10 и жестко закодировать его для использования в Win7 (даже если это нехорошо).

ShixX 03.04.2019 09:48

Чаще всего я вижу наборы параметров, повторяющиеся в демонстрационных данных, поэтому я ожидаю, что их можно будет извлечь из полезной нагрузки. SDK, специфичный для поставщика, обычно предлагает это как вариант для повторения наборов параметров, однако, когда дело доходит до MFT их кодировщика, я помню только, что AMD не повторяет их с I-кадрами.

Roman R. 03.04.2019 10:06

Другие вопросы по теме