Я хочу использовать 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.
Закодированные кадры нужны где-то еще, поэтому я не могу просто пропустить кодирование и положить свои кадры прямо в сток.





Некоторые кодировщики, например, если я правильно помню, довольно популярные и доступные в 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 самостоятельно.
(У меня нет Win7, чтобы проверить) может быть, тогда вы можете извлечь заголовок из полезной нагрузки? Это должно быть довольно просто - использовать первый вывод кодировщика.
Заголовок не включается в полезную нагрузку. По крайней мере, вы не можете извлечь его ни из одного из выходов энкодера. У меня была возможность попробовать это на компьютере с Win10, где все работает отлично. Позже я попытаюсь извлечь заголовок на компьютере с Win10 и жестко закодировать его для использования в Win7 (даже если это нехорошо).
Чаще всего я вижу наборы параметров, повторяющиеся в демонстрационных данных, поэтому я ожидаю, что их можно будет извлечь из полезной нагрузки. SDK, специфичный для поставщика, обычно предлагает это как вариант для повторения наборов параметров, однако, когда дело доходит до MFT их кодировщика, я помню только, что AMD не повторяет их с I-кадрами.
Действительно, я использую Windows 7 Intel Quick Sync. однако
m_pEncoder->ProcessOutput-метод никогда не возвращаетMF_E_TRANSFORM_STREAM_CHANGEдаже после нескольких кадров. Я также проверяю, был ли добавленMF_MT_MPEG_SEQUENCE_HEADERпозже, но не повезло. Конечно, жесткое кодирование заголовка предназначено только для целей отладки.