All streams
Search
Write a publication
Pull to refresh

Comments 18

Ну подождите, вы сознательно отошли от использования многопотока (по для меня не очень убедительным причинам), а такое ощущение, что с ним все было бы на этих аппаратах просто отлично.

В том месте, где приходит буфер кадра, ничего не сделать и многопоток ничего не решает. Кадр находится в DirectByteBuffer и его задержка переполняет буфер сессии. И пока он не будет скопирован, его не отпустить. Следующий момент касается помещения в ZIP. А там важно открыть запись позиции поместить файл и закрыть запись позиции. Многопоток ломает файл. Контролировать многопоток это то же самое, что его не использовать.

Каждый DirectByteBuffer скопировать (по значению, конечно) в промежуточный пул буферов, их раздать воркерам конвертирования в dng, их результаты уже через синхронизацию заливать в zip поток. Если основное время - конверсия в dng, то это должно сработать.

Насколько я помню, копирование 50 мегабайт памяти - порядка пары миллисекунд в худшем случае.

Там была проблема, связанная с метаданными камеры, в статье это описано. Т.е. мы не можем формировать днг, пока не получили полную информацию от сессии захвата.
Теоретически можно разнести это по углам, да, и формировать днг, для которых информация есть уже сразу после копирования буфера. Вижу, это действительно дало бы прирост.
Но поднимать код для теста, чтобы это проверить, уже не буду. Просто буду иметь на будущее.
Сейчас уже проведены работы по переносу всей обработки в нативную области, и большой успех уже достигнут. Но синхронизация все еще сохранена (это необходимо на будущее).
В любом случае спасибо, на определенные мысли это навело.

Копирование в нативной области действительно занимает очень мало. А вот в области Java поболее будет, чем пара миллисекунд.

А как, кстати, эти проблемы решены в айфонах? Никак?

Нативной поддержкой от производителя. В новых айфонах будет ProRes RAW.

так а raw то будет

Еще раз? Не понял вопроса.

А как это было сделано в blackmagic pocket самого первого поколения? Там мощнее процессор стоял?

Там скорее всего это всё происходило на уровне ISP, т.е. отдельный модуль на процессоре, который занимается только обработкой картинки, включая сжатие, и надо было только успевать в ZIP складывать. На Андроиде мы получаем RAW-кадр полного разрешения и нам надо сформировать файл еще со всеми тегами. А если надо уменьшить нагрузку на накопитель, то надо с этим кадром что-то сделать, и делать приходится на центральном процессоре или ГПУ, что совсем другое по производительности, нагреву и потреблению ресурсов.
Если бы был отдельно доступен ISP, я думаю, работало бы много шустрее всё.

А как это сделано в magic lantern: конвертирование в dng уже на компьютере?

Как на андроиде. Поэтому это больше похоже на страдания, чем на съемку RAW.

У вас тут получается поток данных 25 МБ * 24 кадра = 600 МБ/с. Тут нужно, по возможности, делать zero copy, то есть уменьшать копирование данных из буфера в буфер.

Я детально не разбирался, но выглядит так, что создание того-же DNG может состоять из приклеивания фиксированного заголовка (и хвоста, если требуется), так как все кадры одинаковы, а не изготовление заголовка с нуля для каждого кадра.

Аналогично с непожатым ZIP-архивом. Все кадры вместе с заголовками должны иметь одинаковый размер, а потому писать их можно и параллельно. А в конце доклеить структуру со списком файлов.

Я бы для эксперимента попробовал бы просто писать сырые данные в файл из нескольких потоков параллельно — без заголовков DNG и ZIP («колбаса» кадров). Просто, чтобы убедиться, что такой поток данных успевает обрабатываться.

Где возможно, zero-copy сделано.
Кадры не одинаковые. Мысль о такой оптимизации посещала меня, но оказалось, что каждый кадр имеет свои метаданные, и они могут вообще ни разу не повториться.
В ZIP писать параллельно нельзя, потому что он ждет открытие записи позиции и ее закрытие после внесения файла. Так он работает.

Главное, чтобы метаданные были фиксированного размера. Тогда и можно будет писать в файл параллельно, так как при фиксированном размере удастся заранее вычислять смещение в файле, где будет лежать каждый кадр.

Я имел в виду, не пользоваться стандартными библиотеками, а написать собственный параллельный обработчик, который знает внутреннее устройство ZIP-файла.

Писать свое это выходит за рамки «Андроид может». Конечно мы уже сделали много своего всякого, и давно перенесли почти весь функционал в нативную область. Но это уже не совсем Андроид, точнее совсем не андроид.

Если операционная система это позвляет, если эти API не входят в число запрещённых для использвания приложениями в сторе, если root не требуется, то, я считаю, это всё-таки Android. Хоть и низкоуровневая реализация, а не готовый высокоуровневый компонент.

На мой взгляд, пережёвывать 600 мегабайт в секунду -- это уже нетривиальная задача. Старые карты памяти, например, банально не справятся с такой записью. А если хранилище ещё и зашифровано (как это сейчас принято), то надо мерить, вообще, пропускную способность криптоускорителя.

Кстати, я бы начал с простого теста. Создал бы в памяти буфер, допустим в 128 мегабайт случайного мусора, а потом стал бы случайные его части размером в 32 мегабайта (для ускорения, выровненные по границе страницы памяти) писать в файл по разным смещениям параллельно, чтобы сэмулировать многопоточную запись кадров видео фиксированного размера. И посмотрел бы, а успевает ли железо шифровать и записывать 600 мегабайт в секунду, в принципе?

Нет уж. Операционная система линукс тогда, а не Андроид. В нативном коде нет ни одной нативной функции из NDK Android. Поэтому я считаю, что это уже не Андроид.
Насчет скорости записи на носитель, современные девайсы справляются с такой нагрузкой, но объем материала ооочень большой.

Sign up to leave a comment.

Articles