En el desarrollo de aplicaciones para SoC HiSilicon (como el Hi3516), la interacción entre el Media Process Platform (MPP) y frameworks como Qt es fundamental. Uno de los puntos críticos es la extracción de frames directamente desde el subsistema de procesamiento de video (VPSS) para su manipulación o almacenamiento en formatos estándar como JPEG.
Acceso a datos desde VPSS
Aunque muchos desarrolladores de HiSilicon optan por procesos independientes que se comunican mediante sockets, la integración directa en Qt permite una gestión más fluida de la interfaz de usuario y la lógica de negocio. Para obtener una imagen, es necesario interactuar con el VPSS para recuperar los datos de los canales configurados.
Funciones principales de la API
HI_MPI_VPSS_GetChnFrame
Esta función permite extraer un frame procesado desde un canal específico del VPSS. Es obligatorio liberar el frame posteriormente para evitar el desbordamiento de los pools de memoria.
HI_S32 HI_MPI_VPSS_GetChnFrame(VPSS_GRP VpssGrp,
VPSS_CHN VpssChn,
VIDEO_FRAME_INFO_S *pstVideoFrame,
HI_S32 s32MilliSec);
- VpssGrp: Identificador del grupo VPSS (rango según el hardware).
- VpssChn: Canal específico dentro del grupo.
- pstVideoFrame: Estructura donde se almacenará la metainformación y punteros del frame.
- s32MilliSec: Tiempo de espera en milisegundos (-1 para bloqueo total, 0 para retorno inmediato).
HI_MPI_VPSS_ReleaseChnFrame
Libera los recursos del frame obtenidos previamente. Sin esta llamada, el sistema dejará de proporcionar frames nuevos tras agotar el buffer.
HI_S32 HI_MPI_VPSS_ReleaseChnFrame(VPSS_GRP VpssGrp,
VPSS_CHN VpssChn,
const VIDEO_FRAME_INFO_S *pstVideoFrame);
Estructuras de Datos Esenciales
La estructura VIDEO_FRAME_S contiene la información física y virtual necesaria para acceder a los píxeles:
typedef struct hiVIDEO_FRAME_S {
HI_U32 u32Width; // Ancho de la imagen
HI_U32 u32Height; // Alto de la imagen
PIXEL_FORMAT_E enPixelFormat; // Formato de píxel (ej. YUV420SP)
HI_U32 u32Stride[3]; // Espaciado de memoria para cada plano
HI_U64 u64PhyAddr[3]; // Dirección física del buffer
HI_U64 u64VirAddr[3]; // Dirección virtual (mapeada en espacio de kernel)
HI_U64 u64PTS; // Timestamp del frame
} VIDEO_FRAME_S;
Implementación de Captura de Frames
A continuación, se presenta un ejemplo de cómo implementar la lógica de captura dentro de un gestor de video en C++/Qt. El objetivo es identificar un canal activo y extraer la información del formato de píxel.
void VideoProcessor::captureVpssData() {
VIDEO_FRAME_INFO_S stFrameInfo;
HI_S32 s32WaitTime = 500; // ms
VPSS_GRP grpId = 0;
VPSS_CHN chnId = 0;
// Intento de obtención del frame desde el grupo 0, canal 0
HI_S32 result = HI_MPI_VPSS_GetChnFrame(grpId, chnId, &stFrameInfo, s32WaitTime);
if (result == HI_SUCCESS) {
// Analizar formato de la imagen obtenida
PIXEL_FORMAT_E fmt = stFrameInfo.stVFrame.enPixelFormat;
qDebug() << "Frame capturado correctamente:";
qDebug() << "Dimensiones:" << stFrameInfo.stVFrame.u32Width << "x" << stFrameInfo.stVFrame.u32Height;
if (fmt == PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
qDebug() << "Formato detectado: YUV420 Semi-Planar";
}
// Proceso de liberación indispensable
HI_MPI_VPSS_ReleaseChnFrame(grpId, chnId, &stFrameInfo);
} else {
qCritical() << "Error al obtener frame del VPSS. Código:" << result;
}
}
Gestión de Memoria y Errores Comunes
Un error recurrente al trabajar con el SDK de HiSilicon es la omisión de la liberación de frames. El sistema operativo asigna una cantidad finita de bloques de memoria (VB - Video Buffers) para el intercambio de datos entre hardware y software. Si se invoca HI_MPI_VPSS_GetChnFrame repetidamente sin su contraparte de liberación, el contador de refeerncias del buffer nunca llega a cero, provocando que las llamadas posteriores fallen por falta de recursos (generalmente después de 20 o 30 capturas).
Para convertir estos datos a archivos JPG, se recomienda el uso de FFmpeg o bibliotecas de codificación por hardware (VENC) integradas en el propio SoC, mapeando las direcciones de memoria virtual obtenidas en la estructura del frame hacia el codificador correspondiente.