Как можно исключить произвольные кадры из видео MP4 с помощью Media Foundation?

В настоящее время я пытаюсь реализовать алгоритм, который может быстро отбрасывать нежелательные кадры из видео MP4 при кодировании в другой MP4 (с использованием Media Foundation).

Часть кодирования кажется неплохой - "Source Reader плюс Sink Writer "удобный и быстрый подход. Вам просто нужно создать IMFSourceReader и IMFSinkWriter, установить исходный собственный тип мультимедиа на писателе, yada, yada, yada и просто loop: source. ReadSample (& sample) -> writer. WriteSample (& образец). Вызов WriteSample () может зависеть от того, "! 2 b отброшено".

Этот наивный подход бесполезен, если вы считаете, что считанные образцы будут «предсказанными кадрами», иначе говоря, P-кадрами в потоках, закодированных в H.264. Удаление любого предыдущего «кадра с внутренним кодированием» (I-кадра или ключевого кадра) перед этим приведет к искажению видео.

Итак, мой вопрос: можно ли (каким-то образом) ввести I-кадр в приемник записи перед возобновлением записи образца в приемнике записи?

Что-то делать с помощью MFSampleExtension_CleanPoint , похоже, не помогает. Я мог бы вручную создать IMFSample (через MFCreateSample), но получить его в правильном формате H.264 может быть непросто.

Любые идеи? Или мысли о других подходах к отбрасыванию кадров при кодировании?


person dh0well    schedule 05.03.2014    source источник


Ответы (1)


Я думаю, что это невозможно без перекодировки видео! Ссылка между кадрами P и I находится в битовом потоке h264, а не в контейнере (MP4). Вы можете безопасно пропускать только кадры, на которые не ссылаются другие кадры:

  • последние P-кадры группы изображений (перед следующим I-кадром)
  • B-кадры

Обычно на эти фреймы не ссылаются, но они могут быть! Это зависит от настроек кодировщика, используемых для создания потока h264.

person CPlusSharp    schedule 06.03.2014
comment
Решением этой проблемы, безусловно, является распаковка потока перед попыткой отбрасывания любого кадра. То есть у меня IMFSourceReader использует MFVideoFormat_YUY12 в качестве выходного IMFMediaType и устанавливает тот же формат на входе IMFSinkWriter. Любая промежуточная обработка между ReadSample () и WriteSample () может тогда полагаться на целые кадры. Цена этого - значительно более медленное кодирование. :( - person dh0well; 07.03.2014