Значение frame-rate
не игнорируется, но оно не делает того, что вы хотите.
Комбинация frame-rate
и i-frame-interval
определяет, как часто I-кадры (также называемые «кадрами синхронизации») появляются в закодированном выводе. Значение частоты кадров также может играть роль в достижении цели bitrate
на некоторых устройствах, но я не уверен в этом (см., например, этот пост).
Кодер MediaCodec
не пропускает кадры. Если вы хотите уменьшить частоту кадров, вы должны сделать это, отправив на него меньше кадров.
Команда screenrecord
не производит "выборку" экрана с фиксированной частотой кадров. Вместо этого каждый кадр, который он получает от компоновщика поверхности (SurfaceFlinger), отправляется кодировщику с соответствующей меткой времени. Если запись экрана получает 60 кадров в секунду, у вас будет вывод 60 кадров в секунду. Если он получает 10 кадров в быстрой последовательности, за которыми следует ничего в течение 5 секунд, а затем еще пару, вы получите именно это в выходном файле.
Вы можете изменить screenrecord
для пропуска кадров, но вы должны быть немного осторожны. Если вы попытаетесь уменьшить максимальную частоту кадров с 60 кадров в секунду до 30 кадров в секунду, пропуская каждый второй кадр, вы рискуете, что в последовательности «кадр0 — кадр1 — длинная_пауза — кадр2» вы пропустите кадр1, а видео будет удерживаться на кадре0. вместо этого показывает не совсем полную анимацию. Таким образом, вам нужно буферизовать кадр, а затем закодировать или отбросить кадр N-1, если разница во времени представления между ним и кадром N составляет ~ 17 мс.
Хитрость заключается в том, что screenrecord
в режиме работы по умолчанию направляет кадры в кодировщик, не касаясь их, поэтому все, что вы видите, это закодированный вывод. Вы не можете произвольно отбрасывать отдельные кадры закодированных данных, поэтому вы действительно хотите, чтобы кодировщик не видел их в первую очередь. Если вы используете источники screenrecord v1.1, вы можете использовать режим "наложения", используемый для --bugreport
, чтобы пусть кадры проходят через screenrecord
на пути к кодировщику.
В некоторых отношениях может быть проще написать постпроцессор, который снижает частоту кадров. Я не знаю, насколько качество будет потеряно при декодировании и перекодировании видео.
Обновление: для примера того, как это сделать грубо, добавьте это в processFrame_l()
:
int64_t droppedFrames = 0;
+ {
+ static int flipflop = 0;
+ flipflop = 1 - flipflop;
+ if (flipflop) {
+ printf("dropping frame %lld\n", frameNumber);
+ return;
+ }
+ }
if (mLastFrameNumber > 0) {
Обратите внимание, что это происходит после updateTexImage()
, который получает следующий буфер, и пропускает вызов swapBuffers()
, который отправляет буфер видеокодеру.
12.03.2014
updateTexImage()
, когда ничего нового не доступно, и он просто снова получит предыдущий кадр, поэтому вам может просто понадобиться отключить таймер, когда новые кадры не поступят, и отправить предыдущий кадр, если его не было. 26.03.2014swapBuffers()
. Код вprocessFrame_l()
фиксирует новый кадр, визуализирует его и меняет местами. Вы можете разделить это, изменив основной цикл так, чтобы он вызывалupdateTexImage()
всякий раз, когда доступен новый кадр, но ничего не рисовал; затем каждые 33,3 мс вы просыпаетесь и выполняете рендеринг + своп. Это даст видео с постоянной частотой 30 кадров в секунду, повторно отправляя один и тот же кадр, когда система простаивает. Если вы этого не хотите, вы можете добавить проверку отправки этого кадра, которая сбрасывается при поступлении нового кадра. 26.03.2014swapBuffers()
как о передаче всего, что я только что нарисовал, в видеокодер. Если вы просто вызоветеswapBuffers()
, ничего не нарисовав, вы будете несчастны.updateTexImage()
означает взять все самое последнее, что мы получили от компоновщика, и поместить его в текстуру GLES. Итак, если вы посмотрите наprocessFrame_l()
, вы увидите, что он захватывает новый кадр (или старый кадр, если ничего нового не появилось), отображает его с некоторым текстом, а затем отправляет его видеокодеру. 27.03.2014setDisplayProjection()
. Вы можете отключить автоматическое вращение устройства в настройках, но я не знаю, подойдет ли вам этот вариант. 27.03.2014