Я хотел бы спросить, можно ли улучшить FPS для записи экрана с наложением.Android mediaProjection + SurfaceView + наложения просмотров
Псевдо структура приложения:
1) Полноэкранный FrameLayout в AppCompatActivity:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
...
>
<RelativeLayout
android:id="@+id/controls"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
...
>
<ImageView
...
/>
<TextView
...
/>
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
2) Камера предварительного просмотра с SurfaceView:
class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
3) Получить SurfaceView (CameraPreview), добавить CameraPreview to FrameLayout, довести до конца
mPreview = new CameraPreview(this, mCamera); //surfaceView
frameLayout.addView(mPreview); //add surfaceView to root: FrameLayout
controls.bringToFront(); //bring controls to top Z-order
4) Создайте поверхность ввода + создайте виртуальный дисплей и визуализируйте виртуальный дисплей на поверхность через MediaProjection.createVirtualDisplay(...)
. Затем используйте MediaMuxer
для потоков аудио/видео мультиплексирования.
Пункт 3: проблема
Когда я строка комментария: controls.bringToFront();
видео имеет ~ 30FPS, но без наложения взглядов в видео.
Когда я разорвал строку: controls.bringToFront();
видео имеет оверлейные виды в видео, но FPS - всего ~ 20.
ИЛИ
Когда я отключить CameraPreview
видео имеет ~ 30к, но без камеры предварительного просмотра.
Проблема может быть, вероятно, с оверлейными видами. Когда я включить овердрафт в режиме отладки на устройстве: see
камера предварительного просмотра овердрафт 1x (фиолетовый)
ImageView является овердрафт 2x (зеленый)
TextView является овердрафт 3x (розовый)
Когда я включаю профилирования GPU Rendering в режим отладки на устройстве: see
У меня есть все бары под зеленой линией (16 мс).
Возможно, у меня что-то неэффективное. Цель - это экран записи с тем же FPS с/без просмотра наложения. Возможно?
Тесты с screenrecord
команды и Hardware Composer:
A) включен просмотров накладкой; включенный просмотр камеры:
$ ./adb shell screenrecord --time-limit 10 --bit-rate 6000000 /storage/sdcard1/demo3.mp4
и результат видеофайл: 1280 x 720; H.264/AVC; 20FPS; Битовая скорость: 4585 кбит/с.
Hardware Composer:
type | handle | hint | flag | tr | blnd | format | source crop (l,t,r,b) | frame | name
HWC | 557cf928d0 | 0000 | 0000 | 04 | 0100 | ? 00000011 | 0.0, 0.0, 1280.0, 720.0 | 0, 0, 720, 1280 | SurfaceView
HWC | 557cf40dd0 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 720.0, 1280.0 | 0, 0, 720, 1280 | com.example.test/com.example.test.RecordActivity
FB TARGET | 557cf3fd00 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 720.0, 1280.0 | 0, 0, 720, 1280 | HWC_FRAMEBUFFER_TARGET
B) отключить оверлей (//controls.bringToFront();
), поэтому только камера предварительного просмотра включена:
$ ./adb shell screenrecord --time-limit 10 --bit-rate 6000000 /storage/sdcard1/demo4.mp4
и результат Видеофайл: 1280 х 720, H.264/AVC; 30FPS; битрейт: 6684 кб/с.
Оборудование Композитор:
type | handle | hint | flag | tr | blnd | format | source crop (l,t,r,b) | frame | name
HWC | 557cf46610 | 0000 | 0000 | 04 | 0100 | ? 00000011 | 0.0, 0.0, 1280.0, 720.0 | 0, 0, 720, 1280 | SurfaceView
FB TARGET | 557cf3fd00 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 720.0, 1280.0 | 0, 0, 720, 1280 | HWC_FRAMEBUFFER_TARGET
С) включен только android:id="@+id/frameLayout"
+ android:id="@+id/controls"
раскладки; включенный просмотр камеры:
$ ./adb shell screenrecord --time-limit 10 --bit-rate 6000000 /storage/sdcard1/demo5.mp4
и результат видеофайл: 1280 x 720; H.264/AVC; 30FPS; бит-скорость: 4280 кбит/с.
Оборудование Композитор:
type | handle | hint | flag | tr | blnd | format | source crop (l,t,r,b) | frame | name
HWC | 557cf6e910 | 0000 | 0000 | 04 | 0100 | ? 00000011 | 0.0, 0.0, 1280.0, 720.0 | 0, 0, 720, 1280 | SurfaceView
FB TARGET | 557cf04f30 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 720.0, 1280.0 | 0, 0, 720, 1280 | HWC_FRAMEBUFFER_TARGET
D) включен толькоandroid:id="@+id/frameLayout"
+ android:id="@+id/controls"
+ <ImageView ...
раскладки; включенный просмотр камеры:
$ ./adb shell screenrecord --time-limit 10 --bit-rate 6000000 /storage/sdcard1/demo3.mp4
и результат видеофайл: 1280 x 720; H.264/AVC; 20FPS; битрейт: 2879 кбит/с.
Hardware Composer:
type | handle | hint | flag | tr | blnd | format | source crop (l,t,r,b) | frame | name
HWC | 557cfa2040 | 0000 | 0000 | 04 | 0100 | ? 00000011 | 0.0, 0.0, 1280.0, 720.0 | 0, 0, 720, 1280 | SurfaceView
HWC | 557cfb6be0 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 590.0, 880.0, 720.0, 1280.0 | 590, 880, 720, 1280 | com.example.test/com.example.test.RecordActivity
FB TARGET | 557cf04f30 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 720.0, 1280.0 | 0, 0, 720, 1280 | HWC_FRAMEBUFFER_TARGET
Тесты с systrace
:
(. Изображения комбинируют с 1,5 изображений до высоты для получения дополнительной информации)
E) с поддержкой наложения, камеры предварительного просмотра, беговая запись:
F) отключить оверлей (//controls.bringToFront();
), камера предварительного просмотра, выполните запись:
G) включен оверлей, отключить Альфа на всех видах, камеры предварительного просмотра, выполните запись:
Оповещения о:
- Неэффективный вид использования альфа:
Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.
=> Для случая G: i disa bled alpha на всех представлениях. Оповещения были удалены, но FPS все еще: 20. - Запланированная задержка:
Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn't block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.
=> еще не решена.
Но это интересно, потому что, когда я комментарий: //controls.bringToFront();
(случай F), так controls
расположение позади камеры предварительного просмотра (если я понимаю), так что альфа по обработке растровых изображений по-прежнему выполняться, но FPS составляет: 30 => хорошо.
Различия, что я видел из сравнения случая E/F/G (масштаб ~ 5 секунд):
- случай F/G: что-то работа на процессорах: 4,5,6,7, ситуационные E нет.
- в
surfaceFlinger
это имя приложения:.. Ком * ПСО (это мой RecordActivity):
случай E: 184 пунктов,
случай F: 312 пунктов,
случай G: 204 пунктов.
Количество элементов аналогично дляSurfaceView
graph. - в
/system/bin/surfaceflinger
: командаonDraw()
Случай E: ломтик: ~ 7000 имеет продолжительность стены: ~ 3300ms,
случая F: ломтик: ~ 11 000 имеет продолжительность стены: ~ 2300ms,
случая G: ломтик: ~ 7800 имеет Продолжительность стены: ~ 3400 мс. - в
/system/bin/surfaceflinger
отBinder_1
кBinder_5
: командамdequeueBuffer
Случай E: дольки: ~ 1200 имеет продолжительность стенки ~ 3500ms,
случая F: ломтик: ~ 2080 имеет продолжительность стенки ~ 38ms,
регистра G: ломтики: ~ 1509 имеет длину стены ~ 3200 мс, - в
/system/bin/mediaserver
вIppExecuterThre
аналогичная ситуация, как вsurfaceflinger
.dequeueBuffer
Случай Е: ломтики: 282 имеет продолжительность стенки ~ 3600ms,
Случай F: ломтиков: 462 имеет продолжительность стенки ~ 117ms,
случае О: ломтиков: 304 имеет продолжительность стенки ~ 3300ms.
Так что удалите альфа из оверлейного обзора, слегка улучшите производительность, но не увеличивайте FPS.
Если вы используете внешний рекордер, например команду 'screenrecord', вы получаете те же результаты? В конфигурации, где приложение записывает со скоростью 20 кадров в секунду, можете ли вы определить, работает ли он при скорости 20 кадров в секунду при записи * не *? (Просто хочу отделить генерацию кадров от поведения записи ... если она работает со скоростью 20 кадров в секунду с включенной или без записи, вы можете удалить MediaProjection из множества вещей, о которых нужно беспокоиться.) – fadden
Сообщение обновлено.(Не пробовали с включенной записью, потому что FPS был очень медленным, с записью через MediaProjection + MediaMuxer и командой 'screenrecord'. Пробовал работать с включенным/отключенным наложением и включенным предварительным просмотром камеры, но без записи.) – t0m
Это, безусловно, повторное нажатие рабочей стены на вашем конкретном устройстве. Запись экрана добавляет композицию слоя графического процессора для виртуального дисплея, а также собственную кодировку видео. На некоторых устройствах запуск «screenrecord» делает заметную разницу в базовых приложениях, а на других вы даже не знаете, что он работает. Тщательный анализ трассировки systrace - это единственный способ действительно увидеть, что происходит под капотом. Вы можете проверить конфигурацию HWC, чтобы увидеть, что все готово; Я добавил примечание к моему ответу о том, где и как смотреть. – fadden