camerad: calculate buffer sizes with VENUS helpers (#37006)

* Revert "NV12 buffer shape helpers (#36683)"

This reverts commit 13efc421c4.

* camerad: calculate buffer sizes with VENUS helpers

* copy header:

* assert aligned

* python nv12 info

* debug

* handle padding

* use the helper
This commit is contained in:
Adeeb Shihadeh
2026-01-19 17:18:22 -08:00
committed by GitHub
parent c179a3ccb7
commit 6c7f3751e7
7 changed files with 631 additions and 32 deletions

View File

@@ -6,14 +6,17 @@
#include "third_party/linux/include/msm_media_info.h"
// Returns NV12 aligned width, height, and buffer size for the given frame.
inline std::tuple<uint32_t, uint32_t, uint32_t> get_nv12_info(int width, int height) {
// the encoder HW tells us the size it wants after setting it up.
// TODO: VENUS_BUFFER_SIZE should give the size, but it's too small. dependent on encoder settings?
const uint32_t nv12_width = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
const uint32_t nv12_height = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
assert(nv12_width == VENUS_UV_STRIDE(COLOR_FMT_NV12, width));
assert(nv12_height / 2 == VENUS_UV_SCANLINES(COLOR_FMT_NV12, height));
const uint32_t nv12_buffer_size = (width <= 1344 ? 2900 : 2346)*nv12_width;
return {nv12_width, nv12_height, nv12_buffer_size};
// Returns NV12 aligned (stride, y_height, uv_height, buffer_size) for the given frame dimensions.
inline std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> get_nv12_info(int width, int height) {
const uint32_t stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
const uint32_t y_height = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
const uint32_t uv_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height);
const uint32_t size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
// Sanity checks for NV12 format assumptions
assert(stride == VENUS_UV_STRIDE(COLOR_FMT_NV12, width));
assert(y_height / 2 == uv_height);
assert((stride * y_height) % 0x1000 == 0); // uv_offset must be page-aligned
return {stride, y_height, uv_height, size};
}

View File

@@ -0,0 +1,21 @@
# Python version of system/camerad/cameras/nv12_info.h
# Calculations from third_party/linux/include/msm_media_info.h (VENUS_BUFFER_SIZE)
def align(val: int, alignment: int) -> int:
return ((val + alignment - 1) // alignment) * alignment
def get_nv12_info(width: int, height: int) -> tuple[int, int, int, int]:
"""Returns (stride, y_height, uv_height, buffer_size) for NV12 frame dimensions."""
stride = align(width, 128)
y_height = align(height, 32)
uv_height = align(height // 2, 16)
# VENUS_BUFFER_SIZE for NV12
y_plane = stride * y_height
uv_plane = stride * uv_height + 4096
size = y_plane + uv_plane + max(16 * 1024, 8 * stride)
size = align(size, 4096)
size += align(width, 512) * 512 # kernel padding for non-aligned frames
size = align(size, 4096)
return stride, y_height, uv_height, size

View File

@@ -12,11 +12,11 @@
#include "media/cam_isp_ife.h"
#include "media/cam_sensor_cmn_header.h"
#include "media/cam_sync.h"
#include "third_party/linux/include/msm_media_info.h"
#include "common/util.h"
#include "common/swaglog.h"
#include "system/camerad/cameras/ife.h"
#include "system/camerad/cameras/nv12_info.h"
#include "system/camerad/cameras/spectra.h"
#include "system/camerad/cameras/bps_blobs.h"
@@ -283,12 +283,11 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c
buf.out_img_width = sensor->frame_width / sensor->out_scale;
buf.out_img_height = (sensor->hdr_offset > 0 ? (sensor->frame_height - sensor->hdr_offset) / 2 : sensor->frame_height) / sensor->out_scale;
std::tie(stride, y_height, yuv_size) = get_nv12_info(buf.out_img_width, buf.out_img_height);
uv_height = y_height / 2;
// size is driven by all the HW that handles frames,
// the video encoder has certain alignment requirements in this case
std::tie(stride, y_height, uv_height, yuv_size) = get_nv12_info(buf.out_img_width, buf.out_img_height);
uv_offset = stride * y_height;
if (cc.output_type != ISP_RAW_OUTPUT) {
uv_offset = ALIGNED_SIZE(uv_offset, 0x1000);
}
open = true;
configISP();

View File

@@ -12,7 +12,6 @@
#include "common/util.h"
#include "common/swaglog.h"
#include "system/camerad/cameras/hw.h"
#include "system/camerad/cameras/nv12_info.h"
#include "system/camerad/cameras/camera_common.h"
#include "system/camerad/sensors/sensor.h"

View File

@@ -43,9 +43,15 @@ def yuv_to_rgb(y, u, v):
def extract_image(buf):
# NV12 format: Y plane followed by interleaved UV plane
# UV plane size is stride * uv_height, where uv_height = align(height/2, 16)
uv_height = ((buf.height // 2) + 15) // 16 * 16
uv_plane_size = buf.stride * uv_height
y = np.array(buf.data[:buf.uv_offset], dtype=np.uint8).reshape((-1, buf.stride))[:buf.height, :buf.width]
u = np.array(buf.data[buf.uv_offset::2], dtype=np.uint8).reshape((-1, buf.stride//2))[:buf.height//2, :buf.width//2]
v = np.array(buf.data[buf.uv_offset+1::2], dtype=np.uint8).reshape((-1, buf.stride//2))[:buf.height//2, :buf.width//2]
uv_data = buf.data[buf.uv_offset:buf.uv_offset + uv_plane_size]
u = np.array(uv_data[::2], dtype=np.uint8).reshape((-1, buf.stride//2))[:buf.height//2, :buf.width//2]
v = np.array(uv_data[1::2], dtype=np.uint8).reshape((-1, buf.stride//2))[:buf.height//2, :buf.width//2]
return yuv_to_rgb(y, u, v)

View File

@@ -2,7 +2,9 @@
#define __MEDIA_INFO_H__
#ifndef MSM_MEDIA_ALIGN
#define MSM_MEDIA_ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1)))
#define MSM_MEDIA_ALIGN(__sz, __align) (((__align) & ((__align) - 1)) ?\
((((__sz) + (__align) - 1) / (__align)) * (__align)) :\
(((__sz) + (__align) - 1) & (~((__align) - 1))))
#endif
#ifndef MSM_MEDIA_ROUNDUP
@@ -148,7 +150,12 @@ enum color_fmts {
* + 2*(UV_Stride * UV_Scanlines) + Extradata), 4096)
*/
COLOR_FMT_NV12_MVTB,
/* Venus NV12 UBWC:
/*
* The buffer can be of 2 types:
* (1) Venus NV12 UBWC Progressive
* (2) Venus NV12 UBWC Interlaced
*
* (1) Venus NV12 UBWC Progressive Buffer Format:
* Compressed Macro-tile format for NV12.
* Contains 4 planes in the following order -
* (A) Y_Meta_Plane
@@ -234,6 +241,186 @@ enum color_fmts {
* Total size = align( Y_UBWC_Plane_size + UV_UBWC_Plane_size +
* Y_Meta_Plane_size + UV_Meta_Plane_size
* + max(Extradata, Y_Stride * 48), 4096)
*
*
* (2) Venus NV12 UBWC Interlaced Buffer Format:
* Compressed Macro-tile format for NV12 interlaced.
* Contains 8 planes in the following order -
* (A) Y_Meta_Top_Field_Plane
* (B) Y_UBWC_Top_Field_Plane
* (C) UV_Meta_Top_Field_Plane
* (D) UV_UBWC_Top_Field_Plane
* (E) Y_Meta_Bottom_Field_Plane
* (F) Y_UBWC_Bottom_Field_Plane
* (G) UV_Meta_Bottom_Field_Plane
* (H) UV_UBWC_Bottom_Field_Plane
* Y_Meta_Top_Field_Plane consists of meta information to decode
* compressed tile data for Y_UBWC_Top_Field_Plane.
* Y_UBWC_Top_Field_Plane consists of Y data in compressed macro-tile
* format for top field of an interlaced frame.
* UBWC decoder block will use the Y_Meta_Top_Field_Plane data together
* with Y_UBWC_Top_Field_Plane data to produce loss-less uncompressed
* 8 bit Y samples for top field of an interlaced frame.
*
* UV_Meta_Top_Field_Plane consists of meta information to decode
* compressed tile data in UV_UBWC_Top_Field_Plane.
* UV_UBWC_Top_Field_Plane consists of UV data in compressed macro-tile
* format for top field of an interlaced frame.
* UBWC decoder block will use UV_Meta_Top_Field_Plane data together
* with UV_UBWC_Top_Field_Plane data to produce loss-less uncompressed
* 8 bit subsampled color difference samples for top field of an
* interlaced frame.
*
* Each tile in Y_UBWC_Top_Field_Plane/UV_UBWC_Top_Field_Plane is
* independently decodable and randomly accessible. There is no
* dependency between tiles.
*
* Y_Meta_Bottom_Field_Plane consists of meta information to decode
* compressed tile data for Y_UBWC_Bottom_Field_Plane.
* Y_UBWC_Bottom_Field_Plane consists of Y data in compressed macro-tile
* format for bottom field of an interlaced frame.
* UBWC decoder block will use the Y_Meta_Bottom_Field_Plane data
* together with Y_UBWC_Bottom_Field_Plane data to produce loss-less
* uncompressed 8 bit Y samples for bottom field of an interlaced frame.
*
* UV_Meta_Bottom_Field_Plane consists of meta information to decode
* compressed tile data in UV_UBWC_Bottom_Field_Plane.
* UV_UBWC_Bottom_Field_Plane consists of UV data in compressed
* macro-tile format for bottom field of an interlaced frame.
* UBWC decoder block will use UV_Meta_Bottom_Field_Plane data together
* with UV_UBWC_Bottom_Field_Plane data to produce loss-less
* uncompressed 8 bit subsampled color difference samples for bottom
* field of an interlaced frame.
*
* Each tile in Y_UBWC_Bottom_Field_Plane/UV_UBWC_Bottom_Field_Plane is
* independently decodable and randomly accessible. There is no
* dependency between tiles.
*
* <-----Y_TF_Meta_Stride---->
* <-------- Width ------>
* M M M M M M M M M M M M . . ^ ^
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . Half_height |
* M M M M M M M M M M M M . . | Meta_Y_TF_Scanlines
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . V |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . V
* <-Compressed tile Y_TF Stride->
* <------- Width ------->
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_TF_Scanlines
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . V |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . . . V
* <----UV_TF_Meta_Stride---->
* M M M M M M M M M M M M . . ^
* M M M M M M M M M M M M . . |
* M M M M M M M M M M M M . . |
* M M M M M M M M M M M M . . M_UV_TF_Scanlines
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . V
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* <-Compressed tile UV_TF Stride->
* U* V* U* V* U* V* U* V* . . . . ^
* U* V* U* V* U* V* U* V* . . . . |
* U* V* U* V* U* V* U* V* . . . . |
* U* V* U* V* U* V* U* V* . . . . UV_TF_Scanlines
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . V
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* <-----Y_BF_Meta_Stride---->
* <-------- Width ------>
* M M M M M M M M M M M M . . ^ ^
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . Half_height |
* M M M M M M M M M M M M . . | Meta_Y_BF_Scanlines
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . V |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . V
* <-Compressed tile Y_BF Stride->
* <------- Width ------->
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_BF_Scanlines
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . V |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . . . V
* <----UV_BF_Meta_Stride---->
* M M M M M M M M M M M M . . ^
* M M M M M M M M M M M M . . |
* M M M M M M M M M M M M . . |
* M M M M M M M M M M M M . . M_UV_BF_Scanlines
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . V
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* <-Compressed tile UV_BF Stride->
* U* V* U* V* U* V* U* V* . . . . ^
* U* V* U* V* U* V* U* V* . . . . |
* U* V* U* V* U* V* U* V* . . . . |
* U* V* U* V* U* V* U* V* . . . . UV_BF_Scanlines
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . V
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
*
* Half_height = (Height+1)>>1
* Y_TF_Stride = align(Width, 128)
* UV_TF_Stride = align(Width, 128)
* Y_TF_Scanlines = align(Half_height, 32)
* UV_TF_Scanlines = align((Half_height+1)/2, 32)
* Y_UBWC_TF_Plane_size = align(Y_TF_Stride * Y_TF_Scanlines, 4096)
* UV_UBWC_TF_Plane_size = align(UV_TF_Stride * UV_TF_Scanlines, 4096)
* Y_TF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
* Y_TF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16)
* Y_TF_Meta_Plane_size =
* align(Y_TF_Meta_Stride * Y_TF_Meta_Scanlines, 4096)
* UV_TF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
* UV_TF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16)
* UV_TF_Meta_Plane_size =
* align(UV_TF_Meta_Stride * UV_TF_Meta_Scanlines, 4096)
* Y_BF_Stride = align(Width, 128)
* UV_BF_Stride = align(Width, 128)
* Y_BF_Scanlines = align(Half_height, 32)
* UV_BF_Scanlines = align((Half_height+1)/2, 32)
* Y_UBWC_BF_Plane_size = align(Y_BF_Stride * Y_BF_Scanlines, 4096)
* UV_UBWC_BF_Plane_size = align(UV_BF_Stride * UV_BF_Scanlines, 4096)
* Y_BF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
* Y_BF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16)
* Y_BF_Meta_Plane_size =
* align(Y_BF_Meta_Stride * Y_BF_Meta_Scanlines, 4096)
* UV_BF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
* UV_BF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16)
* UV_BF_Meta_Plane_size =
* align(UV_BF_Meta_Stride * UV_BF_Meta_Scanlines, 4096)
* Extradata = 8k
*
* Total size = align( Y_UBWC_TF_Plane_size + UV_UBWC_TF_Plane_size +
* Y_TF_Meta_Plane_size + UV_TF_Meta_Plane_size +
* Y_UBWC_BF_Plane_size + UV_UBWC_BF_Plane_size +
* Y_BF_Meta_Plane_size + UV_BF_Meta_Plane_size +
* + max(Extradata, Y_TF_Stride * 48), 4096)
*/
COLOR_FMT_NV12_UBWC,
/* Venus NV12 10-bit UBWC:
@@ -399,8 +586,233 @@ enum color_fmts {
* Extradata, 4096)
*/
COLOR_FMT_RGBA8888_UBWC,
/* Venus RGBA1010102 UBWC format:
* Contains 2 planes in the following order -
* (A) Meta plane
* (B) RGBA plane
*
* <--- RGB_Meta_Stride ---->
* <-------- Width ------>
* M M M M M M M M M M M M . . ^ ^
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . Height |
* M M M M M M M M M M M M . . | Meta_RGB_Scanlines
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . V |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . V
* <-------- RGB_Stride -------->
* <------- Width ------->
* R R R R R R R R R R R R . . . . ^ ^
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . Height |
* R R R R R R R R R R R R . . . . | RGB_Scanlines
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . V |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . . . V
*
* RGB_Stride = align(Width * 4, 256)
* RGB_Scanlines = align(Height, 16)
* RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096)
* RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64)
* RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16)
* RGB_Meta_Plane_size = align(RGB_Meta_Stride *
* RGB_Meta_Scanlines, 4096)
* Extradata = 8k
*
* Total size = align(RGB_Meta_Plane_size + RGB_Plane_size +
* Extradata, 4096)
*/
COLOR_FMT_RGBA1010102_UBWC,
/* Venus RGB565 UBWC format:
* Contains 2 planes in the following order -
* (A) Meta plane
* (B) RGB plane
*
* <--- RGB_Meta_Stride ---->
* <-------- Width ------>
* M M M M M M M M M M M M . . ^ ^
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . Height |
* M M M M M M M M M M M M . . | Meta_RGB_Scanlines
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . V |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . V
* <-------- RGB_Stride -------->
* <------- Width ------->
* R R R R R R R R R R R R . . . . ^ ^
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . Height |
* R R R R R R R R R R R R . . . . | RGB_Scanlines
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . | |
* R R R R R R R R R R R R . . . . V |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . . . V
*
* RGB_Stride = align(Width * 2, 128)
* RGB_Scanlines = align(Height, 16)
* RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096)
* RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64)
* RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16)
* RGB_Meta_Plane_size = align(RGB_Meta_Stride *
* RGB_Meta_Scanlines, 4096)
* Extradata = 8k
*
* Total size = align(RGB_Meta_Plane_size + RGB_Plane_size +
* Extradata, 4096)
*/
COLOR_FMT_RGB565_UBWC,
/* P010 UBWC:
* Compressed Macro-tile format for NV12.
* Contains 4 planes in the following order -
* (A) Y_Meta_Plane
* (B) Y_UBWC_Plane
* (C) UV_Meta_Plane
* (D) UV_UBWC_Plane
*
* Y_Meta_Plane consists of meta information to decode compressed
* tile data in Y_UBWC_Plane.
* Y_UBWC_Plane consists of Y data in compressed macro-tile format.
* UBWC decoder block will use the Y_Meta_Plane data together with
* Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples.
*
* UV_Meta_Plane consists of meta information to decode compressed
* tile data in UV_UBWC_Plane.
* UV_UBWC_Plane consists of UV data in compressed macro-tile format.
* UBWC decoder block will use UV_Meta_Plane data together with
* UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2
* subsampled color difference samples.
*
* Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable
* and randomly accessible. There is no dependency between tiles.
*
* <----- Y_Meta_Stride ----->
* <-------- Width ------>
* M M M M M M M M M M M M . . ^ ^
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . Height |
* M M M M M M M M M M M M . . | Meta_Y_Scanlines
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . | |
* M M M M M M M M M M M M . . V |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . V
* <--Compressed tile Y Stride--->
* <------- Width ------->
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_Scanlines
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . | |
* Y* Y* Y* Y* Y* Y* Y* Y* . . . . V |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* . . . . . . . . . . . . . . . . V
* <----- UV_Meta_Stride ---->
* M M M M M M M M M M M M . . ^
* M M M M M M M M M M M M . . |
* M M M M M M M M M M M M . . |
* M M M M M M M M M M M M . . M_UV_Scanlines
* . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . V
* . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
* <--Compressed tile UV Stride--->
* U* V* U* V* U* V* U* V* . . . . ^
* U* V* U* V* U* V* U* V* . . . . |
* U* V* U* V* U* V* U* V* . . . . |
* U* V* U* V* U* V* U* V* . . . . UV_Scanlines
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . V
* . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k
*
*
* Y_Stride = align(Width * 2, 256)
* UV_Stride = align(Width * 2, 256)
* Y_Scanlines = align(Height, 16)
* UV_Scanlines = align(Height/2, 16)
* Y_UBWC_Plane_Size = align(Y_Stride * Y_Scanlines, 4096)
* UV_UBWC_Plane_Size = align(UV_Stride * UV_Scanlines, 4096)
* Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
* Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16)
* Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096)
* UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
* UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16)
* UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096)
* Extradata = 8k
*
* Total size = align(Y_UBWC_Plane_size + UV_UBWC_Plane_size +
* Y_Meta_Plane_size + UV_Meta_Plane_size
* + max(Extradata, Y_Stride * 48), 4096)
*/
COLOR_FMT_P010_UBWC,
/* Venus P010:
* YUV 4:2:0 image with a plane of 10 bit Y samples followed
* by an interleaved U/V plane containing 10 bit 2x2 subsampled
* colour difference samples.
*
* <-------- Y/UV_Stride -------->
* <------- Width ------->
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . | |
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height |
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . | |
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . | |
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . | |
* Y Y Y Y Y Y Y Y Y Y Y Y . . . . V |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . V
* U V U V U V U V U V U V . . . . ^
* U V U V U V U V U V U V . . . . |
* U V U V U V U V U V U V . . . . |
* U V U V U V U V U V U V . . . . UV_Scanlines
* . . . . . . . . . . . . . . . . |
* . . . . . . . . . . . . . . . . V
* . . . . . . . . . . . . . . . . --> Buffer size alignment
*
* Y_Stride : Width * 2 aligned to 128
* UV_Stride : Width * 2 aligned to 128
* Y_Scanlines: Height aligned to 32
* UV_Scanlines: Height/2 aligned to 16
* Extradata: Arbitrary (software-imposed) padding
* Total size = align((Y_Stride * Y_Scanlines
* + UV_Stride * UV_Scanlines
* + max(Extradata, Y_Stride * 8), 4096)
*/
COLOR_FMT_P010,
};
#define COLOR_FMT_RGBA1010102_UBWC COLOR_FMT_RGBA1010102_UBWC
#define COLOR_FMT_RGB565_UBWC COLOR_FMT_RGB565_UBWC
#define COLOR_FMT_P010_UBWC COLOR_FMT_P010_UBWC
#define COLOR_FMT_P010 COLOR_FMT_P010
static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height)
{
(void)height;
@@ -413,9 +825,17 @@ static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height)
return 16 * 1024;
}
/*
* Function arguments:
* @color_fmt
* @width
* Progressive: width
* Interlaced: width
*/
static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width)
{
unsigned int alignment, stride = 0;
if (!width)
goto invalid_input;
@@ -432,6 +852,14 @@ static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width)
stride = MSM_MEDIA_ALIGN(width, 192);
stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment);
break;
case COLOR_FMT_P010_UBWC:
alignment = 256;
stride = MSM_MEDIA_ALIGN(width * 2, alignment);
break;
case COLOR_FMT_P010:
alignment = 128;
stride = MSM_MEDIA_ALIGN(width*2, alignment);
break;
default:
break;
}
@@ -439,9 +867,17 @@ invalid_input:
return stride;
}
/*
* Function arguments:
* @color_fmt
* @width
* Progressive: width
* Interlaced: width
*/
static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width)
{
unsigned int alignment, stride = 0;
if (!width)
goto invalid_input;
@@ -458,6 +894,14 @@ static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width)
stride = MSM_MEDIA_ALIGN(width, 192);
stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment);
break;
case COLOR_FMT_P010_UBWC:
alignment = 256;
stride = MSM_MEDIA_ALIGN(width * 2, alignment);
break;
case COLOR_FMT_P010:
alignment = 128;
stride = MSM_MEDIA_ALIGN(width*2, alignment);
break;
default:
break;
}
@@ -465,9 +909,17 @@ invalid_input:
return stride;
}
/*
* Function arguments:
* @color_fmt
* @height
* Progressive: height
* Interlaced: (height+1)>>1
*/
static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height)
{
unsigned int alignment, sclines = 0;
if (!height)
goto invalid_input;
@@ -476,9 +928,11 @@ static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height)
case COLOR_FMT_NV12:
case COLOR_FMT_NV12_MVTB:
case COLOR_FMT_NV12_UBWC:
case COLOR_FMT_P010:
alignment = 32;
break;
case COLOR_FMT_NV12_BPP10_UBWC:
case COLOR_FMT_P010_UBWC:
alignment = 16;
break;
default:
@@ -489,9 +943,17 @@ invalid_input:
return sclines;
}
/*
* Function arguments:
* @color_fmt
* @height
* Progressive: height
* Interlaced: (height+1)>>1
*/
static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height)
{
unsigned int alignment, sclines = 0;
if (!height)
goto invalid_input;
@@ -500,6 +962,8 @@ static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height)
case COLOR_FMT_NV12:
case COLOR_FMT_NV12_MVTB:
case COLOR_FMT_NV12_BPP10_UBWC:
case COLOR_FMT_P010_UBWC:
case COLOR_FMT_P010:
alignment = 16;
break;
case COLOR_FMT_NV12_UBWC:
@@ -509,12 +973,19 @@ static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height)
goto invalid_input;
}
sclines = MSM_MEDIA_ALIGN(height / 2, alignment);
sclines = MSM_MEDIA_ALIGN((height+1)>>1, alignment);
invalid_input:
return sclines;
}
/*
* Function arguments:
* @color_fmt
* @width
* Progressive: width
* Interlaced: width
*/
static inline unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width)
{
int y_tile_width = 0, y_meta_stride = 0;
@@ -524,6 +995,7 @@ static inline unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width)
switch (color_fmt) {
case COLOR_FMT_NV12_UBWC:
case COLOR_FMT_P010_UBWC:
y_tile_width = 32;
break;
case COLOR_FMT_NV12_BPP10_UBWC:
@@ -540,6 +1012,13 @@ invalid_input:
return y_meta_stride;
}
/*
* Function arguments:
* @color_fmt
* @height
* Progressive: height
* Interlaced: (height+1)>>1
*/
static inline unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height)
{
int y_tile_height = 0, y_meta_scanlines = 0;
@@ -552,6 +1031,7 @@ static inline unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height)
y_tile_height = 8;
break;
case COLOR_FMT_NV12_BPP10_UBWC:
case COLOR_FMT_P010_UBWC:
y_tile_height = 4;
break;
default:
@@ -565,6 +1045,13 @@ invalid_input:
return y_meta_scanlines;
}
/*
* Function arguments:
* @color_fmt
* @width
* Progressive: width
* Interlaced: width
*/
static inline unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width)
{
int uv_tile_width = 0, uv_meta_stride = 0;
@@ -574,6 +1061,7 @@ static inline unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width)
switch (color_fmt) {
case COLOR_FMT_NV12_UBWC:
case COLOR_FMT_P010_UBWC:
uv_tile_width = 16;
break;
case COLOR_FMT_NV12_BPP10_UBWC:
@@ -583,13 +1071,20 @@ static inline unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width)
goto invalid_input;
}
uv_meta_stride = MSM_MEDIA_ROUNDUP(width / 2, uv_tile_width);
uv_meta_stride = MSM_MEDIA_ROUNDUP((width+1)>>1, uv_tile_width);
uv_meta_stride = MSM_MEDIA_ALIGN(uv_meta_stride, 64);
invalid_input:
return uv_meta_stride;
}
/*
* Function arguments:
* @color_fmt
* @height
* Progressive: height
* Interlaced: (height+1)>>1
*/
static inline unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height)
{
int uv_tile_height = 0, uv_meta_scanlines = 0;
@@ -602,13 +1097,14 @@ static inline unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height)
uv_tile_height = 8;
break;
case COLOR_FMT_NV12_BPP10_UBWC:
case COLOR_FMT_P010_UBWC:
uv_tile_height = 4;
break;
default:
goto invalid_input;
}
uv_meta_scanlines = MSM_MEDIA_ROUNDUP(height / 2, uv_tile_height);
uv_meta_scanlines = MSM_MEDIA_ROUNDUP((height+1)>>1, uv_tile_height);
uv_meta_scanlines = MSM_MEDIA_ALIGN(uv_meta_scanlines, 16);
invalid_input:
@@ -617,7 +1113,8 @@ invalid_input:
static inline unsigned int VENUS_RGB_STRIDE(int color_fmt, int width)
{
unsigned int alignment = 0, stride = 0;
unsigned int alignment = 0, stride = 0, bpp = 4;
if (!width)
goto invalid_input;
@@ -625,14 +1122,19 @@ static inline unsigned int VENUS_RGB_STRIDE(int color_fmt, int width)
case COLOR_FMT_RGBA8888:
alignment = 128;
break;
case COLOR_FMT_RGB565_UBWC:
alignment = 256;
bpp = 2;
break;
case COLOR_FMT_RGBA8888_UBWC:
case COLOR_FMT_RGBA1010102_UBWC:
alignment = 256;
break;
default:
goto invalid_input;
}
stride = MSM_MEDIA_ALIGN(width * 4, alignment);
stride = MSM_MEDIA_ALIGN(width * bpp, alignment);
invalid_input:
return stride;
@@ -650,6 +1152,8 @@ static inline unsigned int VENUS_RGB_SCANLINES(int color_fmt, int height)
alignment = 32;
break;
case COLOR_FMT_RGBA8888_UBWC:
case COLOR_FMT_RGBA1010102_UBWC:
case COLOR_FMT_RGB565_UBWC:
alignment = 16;
break;
default:
@@ -671,6 +1175,8 @@ static inline unsigned int VENUS_RGB_META_STRIDE(int color_fmt, int width)
switch (color_fmt) {
case COLOR_FMT_RGBA8888_UBWC:
case COLOR_FMT_RGBA1010102_UBWC:
case COLOR_FMT_RGB565_UBWC:
rgb_tile_width = 16;
break;
default:
@@ -693,6 +1199,8 @@ static inline unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height)
switch (color_fmt) {
case COLOR_FMT_RGBA8888_UBWC:
case COLOR_FMT_RGBA1010102_UBWC:
case COLOR_FMT_RGB565_UBWC:
rgb_tile_height = 4;
break;
default:
@@ -706,11 +1214,22 @@ invalid_input:
return rgb_meta_scanlines;
}
/*
* Function arguments:
* @color_fmt
* @width
* Progressive: width
* Interlaced: width
* @height
* Progressive: height
* Interlaced: height
*/
static inline unsigned int VENUS_BUFFER_SIZE(
int color_fmt, int width, int height)
{
const unsigned int extra_size = VENUS_EXTRADATA_SIZE(width, height);
unsigned int uv_alignment = 0, size = 0;
unsigned int w_alignment = 512;
unsigned int y_plane, uv_plane, y_stride,
uv_stride, y_sclines, uv_sclines;
unsigned int y_ubwc_plane = 0, uv_ubwc_plane = 0;
@@ -740,6 +1259,18 @@ static inline unsigned int VENUS_BUFFER_SIZE(
size = y_plane + uv_plane +
MSM_MEDIA_MAX(extra_size, 8 * y_stride);
size = MSM_MEDIA_ALIGN(size, 4096);
/* Additional size to cover last row of non-aligned frame */
size += MSM_MEDIA_ALIGN(width, w_alignment) * w_alignment;
size = MSM_MEDIA_ALIGN(size, 4096);
break;
case COLOR_FMT_P010:
uv_alignment = 4096;
y_plane = y_stride * y_sclines;
uv_plane = uv_stride * uv_sclines + uv_alignment;
size = y_plane + uv_plane +
MSM_MEDIA_MAX(extra_size, 8 * y_stride);
size = MSM_MEDIA_ALIGN(size, 4096);
break;
case COLOR_FMT_NV12_MVTB:
uv_alignment = 4096;
@@ -750,6 +1281,30 @@ static inline unsigned int VENUS_BUFFER_SIZE(
size = MSM_MEDIA_ALIGN(size, 4096);
break;
case COLOR_FMT_NV12_UBWC:
y_sclines = VENUS_Y_SCANLINES(color_fmt, (height+1)>>1);
y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
uv_sclines = VENUS_UV_SCANLINES(color_fmt, (height+1)>>1);
uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
y_meta_scanlines =
VENUS_Y_META_SCANLINES(color_fmt, (height+1)>>1);
y_meta_plane = MSM_MEDIA_ALIGN(
y_meta_stride * y_meta_scanlines, 4096);
uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
uv_meta_scanlines =
VENUS_UV_META_SCANLINES(color_fmt, (height+1)>>1);
uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
uv_meta_scanlines, 4096);
size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
uv_meta_plane)*2 +
MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride);
size = MSM_MEDIA_ALIGN(size, 4096);
/* Additional size to cover last row of non-aligned frame */
size += MSM_MEDIA_ALIGN(width, w_alignment) * w_alignment;
size = MSM_MEDIA_ALIGN(size, 4096);
break;
case COLOR_FMT_NV12_BPP10_UBWC:
y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
@@ -767,12 +1322,30 @@ static inline unsigned int VENUS_BUFFER_SIZE(
MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride);
size = MSM_MEDIA_ALIGN(size, 4096);
break;
case COLOR_FMT_P010_UBWC:
y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
y_meta_plane = MSM_MEDIA_ALIGN(
y_meta_stride * y_meta_scanlines, 4096);
uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
uv_meta_scanlines, 4096);
size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
uv_meta_plane;
size = MSM_MEDIA_ALIGN(size, 4096);
break;
case COLOR_FMT_RGBA8888:
rgb_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, 4096);
size = rgb_plane;
size = MSM_MEDIA_ALIGN(size, 4096);
break;
case COLOR_FMT_RGBA8888_UBWC:
case COLOR_FMT_RGBA1010102_UBWC:
case COLOR_FMT_RGB565_UBWC:
rgb_ubwc_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines,
4096);
rgb_meta_stride = VENUS_RGB_META_STRIDE(color_fmt, width);

View File

@@ -1,14 +1,11 @@
#include "tools/replay/camera.h"
#include <cassert>
#include <algorithm>
#include <capnp/dynamic.h>
#include "third_party/linux/include/msm_media_info.h"
#include "tools/replay/util.h"
#include "system/camerad/cameras/nv12_info.h"
#include "tools/replay/util.h"
const int BUFFER_COUNT = 40;
@@ -43,9 +40,10 @@ void CameraServer::startVipcServer() {
if (cam.width > 0 && cam.height > 0) {
rInfo("camera[%d] frame size %dx%d", cam.type, cam.width, cam.height);
auto [nv12_width, nv12_height, nv12_buffer_size] = get_nv12_info(cam.width, cam.height);
auto [stride, y_height, uv_height_, buffer_size] = get_nv12_info(cam.width, cam.height);
(void)uv_height_; // unused in replay
vipc_server_->create_buffers_with_sizes(cam.stream_type, BUFFER_COUNT, cam.width, cam.height,
nv12_buffer_size, nv12_width, nv12_width * nv12_height);
buffer_size, stride, stride * y_height);
if (!cam.thread.joinable()) {
cam.thread = std::thread(&CameraServer::cameraThread, this, std::ref(cam));
}