Я пишу приложение для Android на C ++ и хочу получить GraphicBuffer из блока памяти, который содержит изображение YUV420sp. В частности, у меня есть IMemory из функции обратного вызова dataCallbackTimestamp камеры, которая дает мне блок памяти с изображением видеокадра, и я хочу добавить его в BufferQueue без использования memcpy. Я использую HAL, и у меня нет HAL3 или Camera2, доступной на HW моего клиента (что сделало бы это тривиальным).
В частности, как мне создать нулевую копию ANativeWindowBuffer или GraphicBuffer из пустоты *? Мне нужно иметь возможность отображать 30 таких графических буферов в секунду для видео 4K.
Я просмотрел интернет и примеры, но не могу понять, как это сделать без memcpy (который убивает мою частоту кадров).
Я могу работать с форматами пикселей и т. Д., Но мне нужна помощь в создании фактического GraphicBuffer из памяти.
Короткий ответ: ты не можешь. Память позади GraphicBuffer должна быть выделена ОС в соответствии с требованиями аппаратных блоков (GPU, камеры, видеокодека, дисплея и т. Д.), Которым необходимо получить к ней доступ, должна быть надежно распределена между процессами и т. Д. Пустота * не соответствует этим требованиям.
Я не знаком с API-интерфейсами камеры, но вы хотите получить Surface из любой системы, которая будет использовать буферы, и предоставить эту Surface API-интерфейсам камеры, чтобы они могли создавать буферы. Ниже будет выделен набор графических буферов, совместимых как с производителем (камерой), так и с потребителем, и потоковые кадры через них с нулевыми копиями, если оборудование способно на это.
В дополнение к тому, что говорит Джесси, IMemory — это другой буфер совместно используемой памяти (на основе ashmem), чем GraphicBuffer, и они не совместимы напрямую.
Кроме того, непосредственно подключаясь к dataCallbackTimestamp, вы выходите за пределы общедоступного API камеры в детали реализации.
Они не гарантируют, что они останутся прежними, поэтому вы рискуете сломать свое приложение в будущих (или прошлых) выпусках ОС, используя его.
Поскольку вы используете устаревший API-интерфейс камеры (хорошо, его внутреннюю часть) и старый HAL, вы не сможете здесь многое сделать без какой-либо memcpy.
Вы можете попытаться передать GPU SurfaceTexture в качестве предварительного просмотра API камеры, а затем нарисовать текстуры 4K в EGL на Surface из MediaCodec (во всяком случае, если вы пытаетесь кодировать видео — не знаете, куда идут ваши графические буферы).