1406 lines
40 KiB
C
1406 lines
40 KiB
C
/*
|
|
* Copyright (c) XMEDIA. All rights reserved.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <sys/ioctl.h>
|
|
#include <unistd.h>
|
|
#include <linux/spi/spidev.h>
|
|
#include <pthread.h>
|
|
#include <signal.h>
|
|
|
|
#include "xmedia_msensor.h"
|
|
#include "xmedia_sys.h"
|
|
#include "xmedia_vi.h"
|
|
#include "xmedia_venc.h"
|
|
#include "xmedia_mmz.h"
|
|
|
|
#include "sample_comm.h"
|
|
#include "sample_comm_sys.h"
|
|
#include "sample_comm_vi.h"
|
|
#include "sample_comm_vpss.h"
|
|
#include "sample_comm_vgs.h"
|
|
#include "sample_comm_venc.h"
|
|
#include "sample_comm_isp.h"
|
|
#include "sample_msensor.h"
|
|
|
|
|
|
#define NUMS_IN_BUF 4000 /* max numbers of gyro data or acc data in buffer */
|
|
#define GYRO_BUF_SIZE (sizeof(xmedia_msensor_sample_data) * NUMS_IN_BUF)
|
|
#define ACC_BUF_SIZE (sizeof(xmedia_msensor_sample_data) * NUMS_IN_BUF)
|
|
|
|
#define GYRO_DATA_RECORDER_RANGE 1000
|
|
#define GYRO_DATA_DV_RANGE 1000
|
|
#define GYRO_DATA_ODR 800
|
|
#define ACC_DATA_RANGE 16
|
|
#define ACC_DATA_ODR 800
|
|
|
|
#define INT_MAX 0x7fffffff /* max value for an int */
|
|
#define GYRO_BIN_FILE "./gyro_data.bin"
|
|
#define GYRO_TXT_FILE "./gyro_data.txt"
|
|
#define GYRO_PARSE_FILE "./gyro_parse_data.txt"
|
|
|
|
typedef struct msensor_get_data_info_ {
|
|
xmedia_bool thread_start;
|
|
xmedia_msensor_data_type data_type;
|
|
xmedia_u32 time_intval;
|
|
xmedia_s32 msensor_dev;
|
|
xmedia_s32 venc_chn;
|
|
} msensor_get_data_info;
|
|
|
|
typedef struct msensor_data_info_ {
|
|
xmedia_s32 msensor_dev;
|
|
xmedia_s32 user_id;
|
|
FILE *gyro_bin_fp;
|
|
FILE *gyro_txt_fp;
|
|
} msensor_data_info;
|
|
|
|
static xmedia_bool g_force_exit = XMEDIA_FALSE;
|
|
|
|
xmedia_s32 g_msensor_dev_fd = -1;
|
|
xmedia_msensor_buf_attr g_msensor_attr[XMEDIA_MSENSOR_MAX_DEV_NUM] = { 0 };
|
|
xmedia_s32 g_gyro_data_range = GYRO_DATA_DV_RANGE;
|
|
|
|
static pthread_t g_msensor_pid[XMEDIA_MSENSOR_MAX_DEV_NUM];
|
|
static msensor_get_data_info g_get_data_info[XMEDIA_MSENSOR_MAX_DEV_NUM] = { 0 };
|
|
static sample_comm_sensor_type sample_msensor_sensor_type[MAX_SENSOR_NUM] = {
|
|
SENSOR0_TYPE,SENSOR1_TYPE,SENSOR2_TYPE,SENSOR3_TYPE,SENSOR4_TYPE
|
|
};
|
|
|
|
xmedia_void sample_msensor_handle_sig(xmedia_s32 signo)
|
|
{
|
|
if (SIGINT == signo || SIGTSTP == signo || SIGTERM == signo) {
|
|
g_force_exit = XMEDIA_TRUE;
|
|
}
|
|
}
|
|
|
|
xmedia_s32 sample_msensor_sys_init(sample_sys_config *sys_config)
|
|
{
|
|
xmedia_s32 ret = 0;
|
|
|
|
ret = sample_comm_sys_init(sys_config);
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sample_comm_sys_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
//in online-online mode,vi and vpss must be reset at the same time
|
|
ret = sample_comm_vi_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sample_comm_vi_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_comm_vpss_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sample_comm_vpss_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_comm_venc_init();
|
|
if(ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sample_comm_venc_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
xmedia_void sample_msensor_sys_exit(void)
|
|
{
|
|
sample_comm_venc_exit();
|
|
sample_comm_vpss_exit();
|
|
sample_comm_vi_exit();
|
|
sample_comm_sys_exit();
|
|
}
|
|
|
|
xmedia_void sample_msensor_usage(xmedia_char* args)
|
|
{
|
|
printf("Usage1 : %s [index] \n", args);
|
|
printf("index:\n");
|
|
printf("\t 0) h265 + msensor.\n");
|
|
printf("\t 1) parse msensor data.\n");
|
|
return;
|
|
}
|
|
|
|
xmedia_u32 h265_encode_sei(xmedia_void *dest_buf, xmedia_void *src_buf, xmedia_u32 in_len_bytes,
|
|
xmedia_u32 *out_len_bytes)
|
|
{
|
|
xmedia_u8 *dest = (xmedia_u8 *)dest_buf;
|
|
xmedia_u8 *src = (xmedia_u8 *)src_buf;
|
|
xmedia_s32 tmp_len = 0;
|
|
xmedia_u32 size;
|
|
xmedia_u32 tmp_code;
|
|
xmedia_u32 byte_cnt = 0;
|
|
xmedia_s32 zero_cnt = 0;
|
|
xmedia_s32 k;
|
|
|
|
size = in_len_bytes;
|
|
|
|
dest[byte_cnt++] = 0x00;
|
|
dest[byte_cnt++] = 0x00;
|
|
dest[byte_cnt++] = 0x00;
|
|
dest[byte_cnt++] = 0x1;
|
|
dest[byte_cnt++] = 0x4e;
|
|
dest[byte_cnt++] = 0x1;
|
|
dest[byte_cnt++] = 0xF0;
|
|
|
|
while (size >= 255) {
|
|
size -= 255;
|
|
dest[byte_cnt++] = 0xFF;
|
|
}
|
|
|
|
tmp_code = size;
|
|
dest[byte_cnt++] = tmp_code;
|
|
tmp_len = byte_cnt;
|
|
|
|
if (size == 0) {
|
|
zero_cnt = 1;
|
|
}
|
|
|
|
for (k = 0; k < (xmedia_s32)in_len_bytes; k++) {
|
|
/* true when 0x000000|0x000001|0x000002|0x000003 */
|
|
if ((zero_cnt == 2) && !(src[k] & 0xFC)) {
|
|
dest[byte_cnt++] = 0x03;
|
|
zero_cnt = 0;
|
|
}
|
|
|
|
dest[byte_cnt++] = src[k];
|
|
|
|
if (src[k] == 0x00) {
|
|
zero_cnt++;
|
|
} else {
|
|
zero_cnt = 0;
|
|
}
|
|
}
|
|
|
|
dest[byte_cnt++] = 0x80;
|
|
*out_len_bytes = byte_cnt;
|
|
|
|
return tmp_len;
|
|
}
|
|
|
|
|
|
xmedia_u32 h264_encode_sei(xmedia_void *dest_buf, xmedia_void *src_buf, xmedia_u32 in_len_bytes,
|
|
xmedia_u32 *out_len_bytes)
|
|
{
|
|
xmedia_u8 *dest = (xmedia_u8 *)dest_buf;
|
|
xmedia_u8 *src = (xmedia_u8 *)src_buf;
|
|
xmedia_s32 tmp_len = 0;
|
|
xmedia_u32 size;
|
|
xmedia_u32 tmp_code;
|
|
xmedia_u32 byte_cnt = 0;
|
|
xmedia_s32 zero_cnt = 0;
|
|
xmedia_s32 k;
|
|
|
|
size = in_len_bytes;
|
|
|
|
dest[byte_cnt++] = 0x00;
|
|
dest[byte_cnt++] = 0x00;
|
|
dest[byte_cnt++] = 0x00;
|
|
dest[byte_cnt++] = 0x1;
|
|
dest[byte_cnt++] = 0x6;
|
|
dest[byte_cnt++] = 0xF0;
|
|
|
|
while (size >= 255) {
|
|
size -= 255;
|
|
dest[byte_cnt++] = 0xFF;
|
|
}
|
|
|
|
tmp_code = size;
|
|
dest[byte_cnt++] = tmp_code;
|
|
tmp_len = byte_cnt;
|
|
|
|
if (size == 0) {
|
|
zero_cnt = 1;
|
|
}
|
|
|
|
for (k = 0; k < (xmedia_s32)in_len_bytes; k++) {
|
|
/* true when 0x000000|0x000001|0x000002|0x000003 */
|
|
if ((zero_cnt == 2) && !(src[k] & 0xFC)) {
|
|
dest[byte_cnt++] = 0x03;
|
|
zero_cnt = 0;
|
|
}
|
|
|
|
dest[byte_cnt++] = src[k];
|
|
|
|
if (src[k] == 0x00) {
|
|
zero_cnt++;
|
|
} else {
|
|
zero_cnt = 0;
|
|
}
|
|
}
|
|
|
|
dest[byte_cnt++] = 0x80;
|
|
*out_len_bytes = byte_cnt;
|
|
|
|
return tmp_len;
|
|
}
|
|
|
|
static void save_gyro_data(xmedia_u8 *data, xmedia_s32 datalen, FILE *pfile)
|
|
{
|
|
xmedia_s32 x;
|
|
xmedia_s32 y;
|
|
xmedia_s32 z;
|
|
xmedia_s32 temp;
|
|
xmedia_u64 pts;
|
|
xmedia_u8 * temp_ptr = data;
|
|
xmedia_s32 tmplen = 0;
|
|
xmedia_char buf[128] = {0};
|
|
|
|
if (datalen % 24 != 0) {
|
|
return ;
|
|
}
|
|
while (tmplen + 24 <= datalen) {
|
|
x = *(xmedia_s32 *)temp_ptr;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
y = *(xmedia_s32 *)temp_ptr;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
z = *(xmedia_s32 *)temp_ptr;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
temp = *(xmedia_s32 *)temp_ptr;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
pts = *(xmedia_u64 *)temp_ptr;
|
|
temp_ptr += sizeof(xmedia_u64);
|
|
|
|
tmplen += 24;
|
|
|
|
sprintf(buf, "%12d,%12d,%12d,%12d,%22llu, \n", x, y, z, temp, pts);
|
|
fwrite(buf, strlen(buf), 1, pfile);
|
|
}
|
|
}
|
|
|
|
// 查找4字节起始码 0x00000001
|
|
int find_4byte_start_code(const xmedia_u8* data, int size, int start_pos)
|
|
{
|
|
int i;
|
|
|
|
for (i = start_pos; i < size - 4; i++) {
|
|
if (data[i] == 0x00 && data[i+1] == 0x00 &&
|
|
data[i+2] == 0x00 && data[i+3] == 0x01) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// 防竞争字节处理 - 移除0x03字节
|
|
// 在H.264/H.265中,0x000000, 0x000001, 0x000002, 0x000003前面会插入0x03防止竞争
|
|
xmedia_u8* remove_emulation_prevention_bytes(const xmedia_u8* data, int size, int* new_size)
|
|
{
|
|
xmedia_u8* output;
|
|
int output_index = 0;
|
|
int zero_count = 0;
|
|
|
|
if (size <= 0) {
|
|
*new_size = 0;
|
|
return NULL;
|
|
}
|
|
|
|
// 分配足够大的缓冲区
|
|
output = (xmedia_u8*)malloc(size);
|
|
if (!output) {
|
|
*new_size = 0;
|
|
return NULL;
|
|
}
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
if (zero_count == 2 && data[i] == 0x03) {
|
|
// 找到防竞争字节0x03,跳过它
|
|
zero_count = 0;
|
|
continue;
|
|
}
|
|
|
|
if (data[i] == 0x00) {
|
|
zero_count++;
|
|
} else {
|
|
zero_count = 0;
|
|
}
|
|
|
|
output[output_index++] = data[i];
|
|
}
|
|
|
|
*new_size = output_index;
|
|
return output;
|
|
}
|
|
|
|
// 解析H.264 SEI NAL单元(带防竞争处理)
|
|
int parse_h264_sei_nal(const xmedia_u8* nal_data, int nal_size, FILE *file)
|
|
{
|
|
int rbsp_size;
|
|
xmedia_u8* rbsp_data;
|
|
|
|
int payload_type = 0;
|
|
xmedia_u8 byte;
|
|
|
|
int pos = 1; // 跳过NAL头(1字节)
|
|
|
|
if (nal_size < 2) {
|
|
return 0;
|
|
}
|
|
|
|
// 首先进行防竞争字节处理
|
|
rbsp_data = remove_emulation_prevention_bytes(nal_data, nal_size, &rbsp_size);
|
|
if (!rbsp_data) {
|
|
return 0;
|
|
}
|
|
|
|
pos = 1; // 跳过NAL头(1字节)
|
|
|
|
while (pos < rbsp_size) {
|
|
// 解析payload_type(使用类似UTF-8的变长编码)
|
|
do {
|
|
if (pos >= rbsp_size) {
|
|
break;
|
|
}
|
|
byte = rbsp_data[pos++];
|
|
payload_type += byte;
|
|
} while (byte == 0xFF);
|
|
|
|
if (pos >= rbsp_size) {
|
|
break;
|
|
}
|
|
|
|
// 解析payload_size(使用类似UTF-8的变长编码)
|
|
int payload_size = 0;
|
|
do {
|
|
if (pos >= rbsp_size) {
|
|
break;
|
|
}
|
|
byte = rbsp_data[pos++];
|
|
payload_size += byte;
|
|
} while (byte == 0xFF);
|
|
|
|
if (pos + payload_size > rbsp_size) {
|
|
printf("Warning: SEI payload size exceeds RBSP size\n");
|
|
break;
|
|
}
|
|
|
|
save_gyro_data(rbsp_data+pos, payload_size, file);
|
|
|
|
pos += payload_size;
|
|
|
|
// 跳过rbsp_trailing_bits(如果有)
|
|
if (pos < rbsp_size) {
|
|
// rbsp_trailing_bits以1开始,后面跟0
|
|
if (rbsp_data[pos] == 0x80) {
|
|
pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
free(rbsp_data);
|
|
return 0;
|
|
}
|
|
|
|
// 解析H.265 SEI NAL单元(带防竞争处理)
|
|
int parse_h265_sei_nal(const xmedia_u8* nal_data, int nal_size, FILE *file)
|
|
{
|
|
int rbsp_size;
|
|
xmedia_u8* rbsp_data;
|
|
|
|
int payload_type = 0;
|
|
xmedia_u8 byte;
|
|
|
|
int pos = 2; // 跳过NAL头(1字节)
|
|
|
|
if (nal_size < 3) {
|
|
return 0;
|
|
}
|
|
|
|
// 首先进行防竞争字节处理
|
|
rbsp_data = remove_emulation_prevention_bytes(nal_data, nal_size, &rbsp_size);
|
|
if (!rbsp_data) {
|
|
return 0;
|
|
}
|
|
|
|
pos = 2; // 跳过NAL头(2字节)
|
|
|
|
while (pos < rbsp_size) {
|
|
// 解析payload_type(使用类似UTF-8的变长编码)
|
|
do {
|
|
if (pos >= rbsp_size) {
|
|
break;
|
|
}
|
|
byte = rbsp_data[pos++];
|
|
payload_type += byte;
|
|
} while (byte == 0xFF);
|
|
|
|
if (pos >= rbsp_size) {
|
|
break;
|
|
}
|
|
|
|
// 解析payload_size(使用类似UTF-8的变长编码)
|
|
int payload_size = 0;
|
|
do {
|
|
if (pos >= rbsp_size) {
|
|
break;
|
|
}
|
|
byte = rbsp_data[pos++];
|
|
payload_size += byte;
|
|
} while (byte == 0xFF);
|
|
|
|
if (pos + payload_size > rbsp_size) {
|
|
printf("Warning: SEI payload size exceeds RBSP size\n");
|
|
break;
|
|
}
|
|
|
|
save_gyro_data(rbsp_data+pos, payload_size, file);
|
|
|
|
pos += payload_size;
|
|
|
|
// 跳过rbsp_trailing_bits(如果有)
|
|
if (pos < rbsp_size) {
|
|
// rbsp_trailing_bits以1开始,后面跟0
|
|
if (rbsp_data[pos] == 0x80) {
|
|
pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
free(rbsp_data);
|
|
return 0;
|
|
}
|
|
|
|
|
|
// 从码流中解析SEI数据(带防竞争处理)
|
|
void parse_stream_sei_with_emulation_prevention(const xmedia_u8* stream_data, int stream_size, int is_h265, FILE *file)
|
|
{
|
|
int pos = 0;
|
|
int next_start;
|
|
int nal_size;
|
|
xmedia_u8 nal_header;
|
|
xmedia_u8 nal_unit_type;
|
|
int is_sei_nal = 0;
|
|
int start_code_pos;
|
|
|
|
while (pos < stream_size - 4) {
|
|
// 查找4字节起始码
|
|
start_code_pos = find_4byte_start_code(stream_data, stream_size, pos);
|
|
if (start_code_pos == -1) {
|
|
break;
|
|
}
|
|
|
|
pos = start_code_pos + 4; // 移动到起始码后
|
|
|
|
if (pos >= stream_size) {
|
|
break;
|
|
}
|
|
|
|
// 查找下一个起始码以确定NAL单元大小
|
|
next_start = find_4byte_start_code(stream_data, stream_size, pos);
|
|
if (next_start == -1) {
|
|
nal_size = stream_size - pos;
|
|
} else {
|
|
nal_size = next_start - pos;
|
|
}
|
|
|
|
if (nal_size <= 0) {
|
|
pos += 1;
|
|
continue;
|
|
}
|
|
|
|
// 获取NAL单元类型
|
|
nal_header = stream_data[pos];
|
|
|
|
if (is_h265) {
|
|
nal_unit_type = (nal_header >> 1) & 0x3F; // H.265: 6位类型
|
|
} else {
|
|
nal_unit_type = nal_header & 0x1F; // H.264: 5位类型
|
|
}
|
|
|
|
// 检查是否为SEI NAL单元
|
|
if (is_h265) {
|
|
// H.265: 前缀SEI(39)和后缀SEI(40)
|
|
is_sei_nal = (nal_unit_type == 39 || nal_unit_type == 40);
|
|
} else {
|
|
// H.264: SEI类型为6
|
|
is_sei_nal = (nal_unit_type == 6);
|
|
}
|
|
//printf(" NAL size: %d bytes, Type: %d\n", nal_size, nal_unit_type);
|
|
if (is_sei_nal) {
|
|
if (is_h265) {
|
|
parse_h265_sei_nal(stream_data + pos, nal_size, file);
|
|
} else {
|
|
parse_h264_sei_nal(stream_data + pos, nal_size, file);
|
|
}
|
|
}
|
|
|
|
pos += nal_size;
|
|
}
|
|
|
|
}
|
|
|
|
xmedia_s32 msensor_spi_init(void)
|
|
{
|
|
xmedia_s32 fd, ret;
|
|
xmedia_s32 mode = SPI_MODE_3; /* | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH */
|
|
xmedia_s32 bits = 8;
|
|
xmedia_u64 speed = 10000000;
|
|
xmedia_char *dev = "/dev/spidev2.0";
|
|
|
|
fd = open(dev, O_RDWR);
|
|
if (fd < 0) {
|
|
SAMPLE_PRT("open spi def failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
/* set spi mode */
|
|
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); /* SPI_IOC_WR_MODE32 */
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("can't set spi mode\n");
|
|
goto end;
|
|
}
|
|
|
|
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); /* SPI_IOC_RD_MODE32 */
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("can't get spi mode\n");
|
|
goto end;
|
|
}
|
|
|
|
/*
|
|
* bits per word
|
|
*/
|
|
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("can't set bits per word\n");
|
|
goto end;
|
|
}
|
|
|
|
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("can't get bits per word\n");
|
|
goto end;
|
|
}
|
|
|
|
/* set spi max speed */
|
|
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("can't set bits max speed HZ\n");
|
|
goto end;
|
|
}
|
|
|
|
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("can't set bits max speed HZ\n");
|
|
goto end;
|
|
}
|
|
|
|
printf("spi mode: 0x%x\n", mode);
|
|
printf("bits per word: %d\n", bits);
|
|
printf("max speed: %lld Hz (%lld KHz)\n", speed, speed / 1000); /* speed with precision of 1000 */
|
|
|
|
end:
|
|
close(fd);
|
|
return ret;
|
|
}
|
|
|
|
|
|
xmedia_s32 msensor_init(xmedia_s32 dev)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_u32 buf_size = GYRO_BUF_SIZE + ACC_BUF_SIZE;
|
|
xmedia_char buf_name[20] = { 0 };
|
|
xmedia_msensor_param param;
|
|
|
|
snprintf(buf_name, sizeof(buf_name), "msensor_dev%d", dev);
|
|
g_msensor_attr[dev].phys_addr = xmedia_mmz_alloc(NULL, buf_name, buf_size);
|
|
if (g_msensor_attr[dev].phys_addr == 0) {
|
|
SAMPLE_PRT("alloc mmz for Msensor failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
g_msensor_attr[dev].virt_addr = xmedia_mmz_map(g_msensor_attr[dev].phys_addr, buf_size, XMEDIA_FALSE);
|
|
if (g_msensor_attr[dev].virt_addr == 0) {
|
|
SAMPLE_PRT("msensor malloc mmz map failed\n");
|
|
xmedia_mmz_free(g_msensor_attr[dev].phys_addr);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
(xmedia_void) memset(g_msensor_attr[dev].virt_addr, 0, buf_size);
|
|
|
|
g_msensor_attr[dev].buf_len = buf_size;
|
|
|
|
/* set device work mode */
|
|
param.attr.device_mask = XMEDIA_MSENSOR_DEVICE_GYRO | XMEDIA_MSENSOR_DEVICE_ACC;
|
|
param.attr.temperature_mask = XMEDIA_MSENSOR_TEMP_GYRO | XMEDIA_MSENSOR_TEMP_ACC;
|
|
|
|
/* set gyro samplerate and full scale range */
|
|
param.config.gyro_config.odr = GYRO_DATA_ODR * XMEDIA_MSENSOR_GRADIENT;
|
|
param.config.gyro_config.fsr = g_gyro_data_range * XMEDIA_MSENSOR_GRADIENT;
|
|
/* set accel samplerate and full scale range */
|
|
param.config.acc_config.odr = ACC_DATA_ODR * XMEDIA_MSENSOR_GRADIENT;
|
|
param.config.acc_config.fsr = ACC_DATA_RANGE * XMEDIA_MSENSOR_GRADIENT;
|
|
|
|
(xmedia_void) memcpy(¶m.buf_attr, &g_msensor_attr[dev], sizeof(xmedia_msensor_buf_attr));
|
|
|
|
ret = xmedia_msensor_create_dev(dev, ¶m);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("msensor_create failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
xmedia_void msensor_deinit(xmedia_s32 dev)
|
|
{
|
|
xmedia_s32 ret;
|
|
|
|
ret = xmedia_msensor_destroy_dev(dev);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("msensor deinit failed , ret:0x%x !\n", ret);
|
|
}
|
|
|
|
ret = xmedia_mmz_unmap(g_msensor_attr[dev].virt_addr);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("msensor mmz map failed, ret:0x%x !\n", ret);
|
|
}
|
|
|
|
ret = xmedia_mmz_free(g_msensor_attr[dev].phys_addr);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("msensor mmz free failed, ret:0x%x !\n", ret);
|
|
}
|
|
|
|
g_msensor_attr[dev].phys_addr = 0;
|
|
g_msensor_attr[dev].virt_addr = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
xmedia_s32 msensor_start(xmedia_s32 dev)
|
|
{
|
|
xmedia_s32 ret;
|
|
|
|
printf("spi init\n");
|
|
|
|
ret = msensor_spi_init();
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("init spi fail.ret:0x%x !\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
printf("spi init ok\n");
|
|
|
|
ret = msensor_init(dev);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("init gyro fail.ret:0x%x !\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = xmedia_msensor_start_dev(dev);;
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("start gyro fail.ret:0x%x !\n", ret);
|
|
goto msensor_start_fail;
|
|
}
|
|
|
|
printf("motion sensor start ok\n");
|
|
return XMEDIA_SUCCESS;
|
|
|
|
msensor_start_fail:
|
|
msensor_deinit(dev);
|
|
|
|
return ret;
|
|
}
|
|
|
|
xmedia_void msensor_stop(xmedia_s32 dev)
|
|
{
|
|
xmedia_msensor_stop_dev(dev);;
|
|
msensor_deinit(dev);
|
|
|
|
return;
|
|
}
|
|
|
|
xmedia_venc_stream *msensor_mix_gyro_stream(xmedia_payload_type payload_type, FILE* pFd, xmedia_venc_stream* pstStream, xmedia_u32 stream_idex, msensor_data_info *pstdata_info)
|
|
{
|
|
xmedia_s32 i;
|
|
xmedia_msensor_data_info gyro_data;
|
|
static xmedia_venc_stream *last_stream = XMEDIA_NULL;
|
|
static xmedia_u32 delta_pts = 0;
|
|
xmedia_venc_stream *temp_stream;
|
|
xmedia_s32 addr_offset;
|
|
xmedia_s32 x;
|
|
xmedia_s32 y;
|
|
xmedia_s32 z;
|
|
xmedia_s32 temp;
|
|
xmedia_u64 pts;
|
|
static xmedia_char *gyro_data_buf = XMEDIA_NULL;
|
|
static xmedia_char *sei_data_buf = XMEDIA_NULL;
|
|
xmedia_u32 gyro_data_len = 0;
|
|
xmedia_u32 sei_data_len = 0;
|
|
xmedia_char * txt_buf;
|
|
xmedia_char txt_tmp[128] = {0};
|
|
xmedia_u32 txt_pos = 0;
|
|
xmedia_char * temp_ptr;
|
|
int cyclic;
|
|
xmedia_s32 ret;
|
|
xmedia_s32 msensor_dev;
|
|
xmedia_s32 user_id;
|
|
|
|
if (payload_type != PT_H264 && payload_type != PT_H265) {
|
|
return pstStream;
|
|
}
|
|
|
|
if (stream_idex == 0) {
|
|
last_stream = pstStream;
|
|
if (gyro_data_buf == XMEDIA_NULL) {
|
|
gyro_data_buf = malloc(4*1024);
|
|
}
|
|
|
|
if (sei_data_buf == XMEDIA_NULL) {
|
|
sei_data_buf = malloc(6*1024);
|
|
}
|
|
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
if ((gyro_data_buf == XMEDIA_NULL) || (sei_data_buf == XMEDIA_NULL)) {
|
|
return pstStream;
|
|
}
|
|
|
|
msensor_dev = pstdata_info->msensor_dev;
|
|
user_id = pstdata_info->user_id;
|
|
|
|
gyro_data.id = user_id;
|
|
gyro_data.data_type = XMEDIA_MSENSOR_DATA_TYPE_GYRO;
|
|
if (stream_idex != 0xFFFFFFFF) {
|
|
delta_pts = pstStream->pack[0].pts - last_stream->pack[0].pts;
|
|
gyro_data.begin_pts = last_stream->pack[0].pts;
|
|
gyro_data.end_pts = pstStream->pack[0].pts;
|
|
} else {
|
|
gyro_data.begin_pts = last_stream->pack[0].pts;
|
|
gyro_data.end_pts = gyro_data.begin_pts + delta_pts;
|
|
}
|
|
|
|
ret = xmedia_msensor_get_data(msensor_dev, &gyro_data);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("msensor get data failed, pts[%lld]-pts[%lld] ret:0x%x !\n", gyro_data.begin_pts, gyro_data.end_pts, ret);
|
|
temp_stream = last_stream;
|
|
last_stream = pstStream;
|
|
|
|
if (stream_idex == 0xFFFFFFFF) {
|
|
temp_stream = last_stream;
|
|
last_stream = XMEDIA_NULL;
|
|
|
|
if (gyro_data_buf) {
|
|
free(gyro_data_buf);
|
|
gyro_data_buf = XMEDIA_NULL;
|
|
}
|
|
|
|
if (sei_data_buf) {
|
|
free(sei_data_buf);
|
|
sei_data_buf = XMEDIA_NULL;
|
|
}
|
|
}
|
|
return temp_stream;
|
|
}
|
|
|
|
|
|
//SAMPLE_PRT("get gyro data start pts %llu, end pts %llu, diff %llu, num %d %d\n", gyro_data.begin_pts,
|
|
// gyro_data.end_pts, gyro_data.end_pts - gyro_data.begin_pts, gyro_data.data[0].num,
|
|
// gyro_data.data[1].num);usleep(100000);
|
|
|
|
gyro_data_len = (gyro_data.data[0].num + gyro_data.data[1].num) * 24;
|
|
temp_ptr = gyro_data_buf;
|
|
addr_offset = g_msensor_attr[msensor_dev].phys_addr - (xmedia_u64)(xmedia_uintptr_t)g_msensor_attr[msensor_dev].virt_addr;
|
|
txt_buf = (xmedia_char *)malloc(1024*1024);
|
|
txt_pos = 0;
|
|
memset(txt_tmp, 0, sizeof(txt_tmp));
|
|
|
|
for (cyclic = 0; cyclic < 2; cyclic++) {
|
|
for (i = 0; i < gyro_data.data[cyclic].num; i++) {
|
|
x = *(xmedia_s32 *)(xmedia_uintptr_t)((xmedia_u64)(xmedia_uintptr_t)(gyro_data.data[cyclic].x_phys_addr + i) -
|
|
addr_offset);
|
|
y = *(xmedia_s32 *)(xmedia_uintptr_t)((xmedia_u64)(xmedia_uintptr_t)(gyro_data.data[cyclic].y_phys_addr + i) -
|
|
addr_offset);
|
|
z = *(xmedia_s32 *)(xmedia_uintptr_t)((xmedia_u64)(xmedia_uintptr_t)(gyro_data.data[cyclic].z_phys_addr + i) -
|
|
addr_offset);
|
|
temp = *(xmedia_s32 *)(xmedia_uintptr_t)((xmedia_u64)(xmedia_uintptr_t)(gyro_data.data[cyclic].temperature_phys_addr + i) -
|
|
addr_offset);
|
|
pts =
|
|
*(xmedia_u64 *)(xmedia_uintptr_t)((xmedia_u64)(xmedia_uintptr_t)(gyro_data.data[cyclic].pts_phys_addr + i) -
|
|
addr_offset);
|
|
|
|
*(xmedia_s32 *)temp_ptr = x;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
*(xmedia_s32 *)temp_ptr = y;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
*(xmedia_s32 *)temp_ptr = z;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
*(xmedia_s32 *)temp_ptr = temp;
|
|
temp_ptr += sizeof(xmedia_s32);
|
|
*(xmedia_u64 *)temp_ptr = pts;
|
|
temp_ptr += sizeof(xmedia_u64);
|
|
|
|
if (txt_buf) {
|
|
sprintf(txt_tmp, "%12d,%12d,%12d,%12d,%22llu, \n", x, y, z, temp, pts);
|
|
memcpy(txt_buf+txt_pos, txt_tmp, strlen(txt_tmp));
|
|
txt_pos += strlen(txt_tmp);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (txt_buf) {
|
|
fwrite(txt_buf, txt_pos, 1, pstdata_info->gyro_txt_fp);
|
|
free(txt_buf);
|
|
txt_buf = XMEDIA_NULL;
|
|
}
|
|
|
|
if (payload_type == PT_H264) {
|
|
h264_encode_sei(sei_data_buf, gyro_data_buf, gyro_data_len, &sei_data_len);
|
|
fwrite(sei_data_buf, sei_data_len, 1, pFd);
|
|
if (pstdata_info->gyro_bin_fp) {
|
|
fwrite(sei_data_buf, sei_data_len, 1, pstdata_info->gyro_bin_fp);
|
|
}
|
|
} else if (payload_type == PT_H265) {
|
|
h265_encode_sei(sei_data_buf, gyro_data_buf, gyro_data_len, &sei_data_len);
|
|
fwrite(sei_data_buf, sei_data_len, 1, pFd);
|
|
if (pstdata_info->gyro_bin_fp) {
|
|
fwrite(sei_data_buf, sei_data_len, 1, pstdata_info->gyro_bin_fp);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < last_stream->pack_count; i++) {
|
|
fwrite(last_stream->pack[i].vir_addr + last_stream->pack[i].offset,
|
|
last_stream->pack[i].len - last_stream->pack[i].offset, 1, pFd);
|
|
}
|
|
|
|
if (stream_idex == 0xFFFFFFFF) {
|
|
temp_stream = last_stream;
|
|
last_stream = XMEDIA_NULL;
|
|
|
|
if (gyro_data_buf) {
|
|
free(gyro_data_buf);
|
|
gyro_data_buf = XMEDIA_NULL;
|
|
}
|
|
|
|
if (sei_data_buf) {
|
|
free(sei_data_buf);
|
|
sei_data_buf = XMEDIA_NULL;
|
|
}
|
|
} else {
|
|
|
|
temp_stream = last_stream;
|
|
last_stream = pstStream;
|
|
}
|
|
return temp_stream;
|
|
|
|
}
|
|
|
|
xmedia_void *msensor_get_data_thread(xmedia_void *args)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_s32 msensor_dev;
|
|
xmedia_s32 user_id;
|
|
msensor_data_info msensor_info;
|
|
msensor_get_data_info *get_data_info = (msensor_get_data_info *)args;
|
|
FILE *gyro_bin_fp = XMEDIA_NULL;
|
|
FILE *gyro_txt_fp = XMEDIA_NULL;
|
|
|
|
xmedia_u32 stream_index = 0;
|
|
|
|
//xmedia_u16 temp_pts = 0;
|
|
xmedia_venc_chn_attr venc_chn_attr;
|
|
xmedia_payload_type payload_type;
|
|
|
|
xmedia_char file_name[512];
|
|
xmedia_char *file_path="./";
|
|
FILE *file_ptr;
|
|
|
|
struct timeval time_out;
|
|
xmedia_venc_stream *venc_stream;
|
|
xmedia_venc_chn_status stat;
|
|
xmedia_u32 venc_mask = 0;
|
|
xmedia_venc_stream *temp_stream;
|
|
|
|
printf("start dump gyro data\n");
|
|
|
|
gyro_bin_fp = fopen(GYRO_BIN_FILE, "w+");
|
|
if (gyro_bin_fp == XMEDIA_NULL) {
|
|
SAMPLE_PRT("Error: cannot open imu data\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
gyro_txt_fp = fopen(GYRO_TXT_FILE, "w+");
|
|
if (gyro_txt_fp == XMEDIA_NULL) {
|
|
fclose(gyro_bin_fp);
|
|
SAMPLE_PRT("Error: cannot open imu data\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
ret = xmedia_venc_get_chn_attr(get_data_info->venc_chn, &venc_chn_attr);
|
|
if (XMEDIA_SUCCESS != ret) {
|
|
SAMPLE_PRT("xmedia_venc_get_chn_attr chn[%d] failed with %#x!\n", get_data_info->venc_chn, ret);
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
payload_type = venc_chn_attr.venc_attr.en_type;
|
|
|
|
if (payload_type != PT_H264 && payload_type != PT_H265) {
|
|
goto exit;
|
|
}
|
|
|
|
if (payload_type == PT_H264) {
|
|
snprintf(file_name, 512, "%s/stream_chn%d%s", file_path, get_data_info->venc_chn, ".h264");
|
|
} else {
|
|
snprintf(file_name, 512, "%s/stream_chn%d%s", file_path, get_data_info->venc_chn, ".h265");
|
|
}
|
|
file_ptr = fopen(file_name, "wb");
|
|
if (!file_ptr) {
|
|
SAMPLE_PRT("open file %s failed!\n", file_name);
|
|
return XMEDIA_NULL;
|
|
}
|
|
chmod(file_name, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
|
|
|
venc_mask |= 1 << get_data_info->venc_chn;
|
|
|
|
msensor_dev = get_data_info->msensor_dev;
|
|
ret = xmedia_msensor_add_user(msensor_dev, &user_id);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("msensor add user failed, ret:0x%x !\n", ret);
|
|
goto exit;
|
|
}
|
|
|
|
msensor_info.msensor_dev = msensor_dev;
|
|
msensor_info.user_id = user_id;
|
|
msensor_info.gyro_txt_fp = gyro_txt_fp;
|
|
msensor_info.gyro_bin_fp = gyro_bin_fp;
|
|
|
|
while (get_data_info->thread_start) {
|
|
time_out.tv_sec = 2;
|
|
time_out.tv_usec = 0;
|
|
ret = xmedia_venc_select(venc_mask, &time_out);
|
|
if (ret == XMEDIA_ERRCODE_INVALID_PARAM || ret == XMEDIA_FAILURE) {
|
|
SAMPLE_PRT("select err\n");
|
|
break;
|
|
} else if (ret == XMEDIA_ERRCODE_TIMEOUT) {
|
|
usleep(100 * 1000);
|
|
continue;
|
|
}
|
|
|
|
ret = xmedia_venc_query_status(get_data_info->venc_chn, &stat);
|
|
if (XMEDIA_SUCCESS != ret) {
|
|
SAMPLE_PRT("xmedia_venc_query_status chn[%d] failed with %#x!\n", get_data_info->venc_chn, ret);
|
|
break;
|
|
}
|
|
|
|
if (0 == stat.cur_packs) {
|
|
continue;
|
|
}
|
|
|
|
venc_stream = (xmedia_venc_stream *)malloc(sizeof(xmedia_venc_stream));
|
|
if (XMEDIA_NULL == venc_stream) {
|
|
SAMPLE_PRT("malloc stream pack failed!\n");
|
|
break;
|
|
}
|
|
memset(venc_stream, 0, sizeof(xmedia_venc_stream));
|
|
venc_stream->pack = (xmedia_venc_pack*)malloc(sizeof(xmedia_venc_pack) * stat.cur_packs);
|
|
if (XMEDIA_NULL == venc_stream->pack) {
|
|
SAMPLE_PRT("malloc stream pack failed!\n");
|
|
free(venc_stream);
|
|
break;
|
|
}
|
|
|
|
venc_stream->pack_count = stat.cur_packs;
|
|
ret = xmedia_venc_get_stream(get_data_info->venc_chn, venc_stream, -1);
|
|
if (XMEDIA_SUCCESS != ret) {
|
|
free(venc_stream->pack);
|
|
venc_stream->pack = XMEDIA_NULL;
|
|
free(venc_stream);
|
|
SAMPLE_PRT("xmedia_venc_get_stream failed with %#x!\n", ret);
|
|
break;
|
|
}
|
|
|
|
if (PT_JPEG != payload_type) {
|
|
temp_stream = msensor_mix_gyro_stream(payload_type, file_ptr, venc_stream, stream_index, &msensor_info);
|
|
stream_index++;
|
|
if (XMEDIA_NULL != temp_stream) {
|
|
xmedia_venc_release_stream(get_data_info->venc_chn, temp_stream);
|
|
free(temp_stream->pack);
|
|
temp_stream->pack = XMEDIA_NULL;
|
|
free(temp_stream);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
temp_stream = msensor_mix_gyro_stream(payload_type, file_ptr, XMEDIA_NULL, 0xFFFFFFFF, &msensor_info);
|
|
if (XMEDIA_NULL != temp_stream) {
|
|
xmedia_venc_release_stream(get_data_info->venc_chn, temp_stream);
|
|
free(temp_stream->pack);
|
|
temp_stream->pack = XMEDIA_NULL;
|
|
free(temp_stream);
|
|
}
|
|
|
|
ret = xmedia_msensor_delete_user(msensor_dev, user_id);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("msensor delete user failed, ret:0x%x !\n", ret);
|
|
}
|
|
|
|
exit:
|
|
fclose(gyro_bin_fp);
|
|
fclose(gyro_txt_fp);
|
|
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
xmedia_s32 sample_msensor_parse_data(xmedia_void)
|
|
{
|
|
FILE *file = fopen(GYRO_BIN_FILE, "rb");
|
|
FILE *gyro_parse_fp = XMEDIA_NULL;
|
|
|
|
gyro_parse_fp = fopen(GYRO_PARSE_FILE, "w+");
|
|
if (gyro_parse_fp == XMEDIA_NULL) {
|
|
SAMPLE_PRT("Error: cannot open imu data\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
if (file == NULL) {
|
|
fclose(gyro_parse_fp);
|
|
perror("无法打开文件");
|
|
return 1;
|
|
}
|
|
|
|
// 获取文件大小
|
|
fseek(file, 0, SEEK_END);
|
|
long file_size = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
// 分配内存
|
|
unsigned char *buffer = (unsigned char*)malloc(file_size + 1);
|
|
if (buffer == NULL) {
|
|
perror("内存分配失败");
|
|
fclose(file);
|
|
return 1;
|
|
}
|
|
|
|
// 读取整个文件
|
|
size_t bytes_read = fread(buffer, 1, file_size, file);
|
|
buffer[bytes_read] = '\0'; // 添加字符串结束符
|
|
fclose(file);
|
|
|
|
parse_stream_sei_with_emulation_prevention(buffer, bytes_read, 1, gyro_parse_fp);
|
|
fclose(gyro_parse_fp);
|
|
|
|
// 清理
|
|
free(buffer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
xmedia_s32 sample_msensor_start_dump_data(xmedia_s32 dev)
|
|
{
|
|
|
|
memset(&g_get_data_info[dev], 0, sizeof(msensor_get_data_info));
|
|
|
|
g_get_data_info[dev].thread_start = XMEDIA_TRUE;
|
|
g_get_data_info[dev].data_type = XMEDIA_MSENSOR_DATA_TYPE_GYRO;
|
|
g_get_data_info[dev].time_intval = 4;
|
|
g_get_data_info[dev].msensor_dev = dev;
|
|
pthread_create(&g_msensor_pid[dev], 0, msensor_get_data_thread, (xmedia_void *)&g_get_data_info[dev]);
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
xmedia_s32 sample_msensor_stop_dump_data(xmedia_s32 dev)
|
|
{
|
|
if (XMEDIA_TRUE == g_get_data_info[dev].thread_start) {
|
|
g_get_data_info[dev].thread_start = XMEDIA_FALSE;
|
|
|
|
if (g_msensor_pid[dev] > 0) {
|
|
pthread_join(g_msensor_pid[dev], 0);
|
|
}
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
|
|
xmedia_s32 sample_msensor_init(xmedia_s32 dev_cnt, xmedia_s32 *dev)
|
|
{
|
|
xmedia_s32 i;
|
|
xmedia_s32 ret = XMEDIA_SUCCESS;
|
|
|
|
xmedia_msensor_init();
|
|
|
|
for (i = 0; i < dev_cnt; i++) {
|
|
ret = msensor_start(dev[i]);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
xmedia_void sample_msensor_exit(xmedia_s32 dev_cnt, xmedia_s32 *dev)
|
|
{
|
|
xmedia_s32 i;
|
|
|
|
for (i = 0; i < dev_cnt; i++) {
|
|
msensor_stop(dev[i]);
|
|
}
|
|
xmedia_msensor_exit();
|
|
}
|
|
|
|
xmedia_s32 sample_venc_h265_msensor(xmedia_bool set_roi)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_SUCCESS;
|
|
xmedia_s32 blk_size = 0;
|
|
xmedia_video_size pic_size = { 0 };
|
|
xmedia_video_size sub_pic_size = { 0 };
|
|
sample_comm_video_param video_param = { 0 };
|
|
sample_sys_config sys_config = { 0 };
|
|
xmedia_s32 msensor_dev = 0;
|
|
xmedia_s32 vi_dev = 0;
|
|
xmedia_s32 vi_pipe = 0;
|
|
xmedia_s32 vi_chn = 0;
|
|
sample_vi_config vi_config = { 0 };
|
|
|
|
xmedia_s32 sensor_type = sample_msensor_sensor_type[0];
|
|
xmedia_u32 framerate = 0;
|
|
vi_sensor_info sensor_info = { 0 };
|
|
sample_isp_param isp_param = { 0 };
|
|
xmedia_isp_config isp_config = { 0 };
|
|
xmedia_bool mirror = XMEDIA_FALSE;
|
|
xmedia_bool flip = XMEDIA_FALSE;
|
|
|
|
xmedia_s32 vpss_chnl = 0;
|
|
xmedia_s32 vpss_pipe = 0;
|
|
xmedia_s32 vpss_ichn = 0;
|
|
xmedia_s32 vpss_ochn[1] = { 0 };
|
|
sample_vpss_config vpss_config = { 0 };
|
|
xmedia_video_size vpss_ochn_size[VPSS_MAX_OCHN_NUM] = { 0 };
|
|
|
|
xmedia_s32 venc_chnl = 0;
|
|
xmedia_s32 venc_chn[1] = { 0 };
|
|
xmedia_s32 venc_chn_cnt = 1;
|
|
sample_venc_config venc_config = { 0 };
|
|
xmedia_venc_gop_mode gop_mode;
|
|
|
|
video_param.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
|
|
video_param.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420;
|
|
video_param.data_width = XMEDIA_VIDEO_DATA_WIDTH_8;
|
|
video_param.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
|
|
|
|
sample_comm_vi_get_sensor_info(sensor_type, &sensor_info);
|
|
sample_comm_vi_get_framerate_by_sensor(sensor_type, &framerate);
|
|
|
|
gop_mode = VENC_GOPMODE_NORMALP;
|
|
|
|
// sys init
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].vicap_viproc_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].viproc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].gdc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
|
|
sys_config.vb_conf.max_pool_cnt = 25;
|
|
|
|
pic_size.width = sensor_info.width;
|
|
pic_size.height = sensor_info.height;
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, video_param.video_fmt, sensor_info.pixel_format,
|
|
sensor_info.bit_width, video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[0].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[0].block_cnt = 2;
|
|
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, video_param.video_fmt, video_param.pixel_fmt,
|
|
video_param.data_width, video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[1].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[1].block_cnt = 4;
|
|
|
|
sub_pic_size.width = 640;
|
|
sub_pic_size.height = 480;
|
|
blk_size = sample_comm_sys_get_buffer_size(sub_pic_size, video_param.video_fmt, video_param.pixel_fmt,
|
|
video_param.data_width, video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[2].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[2].block_cnt = 2;
|
|
|
|
sys_config.vb_conf.supplement_config = 1;
|
|
|
|
ret = sample_msensor_sys_init(&sys_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sys init failed !\n");
|
|
return ret;
|
|
}
|
|
|
|
sample_msensor_init(1, &msensor_dev);
|
|
|
|
vi_config.dev_info[vi_dev].dev_en = XMEDIA_TRUE;
|
|
vi_config.dev_info[vi_dev].dev_no = vi_dev;
|
|
vi_config.dev_info[vi_dev].sensor_type = sensor_type;
|
|
vi_config.pipe_info[vi_pipe].pipe_en = XMEDIA_TRUE;
|
|
vi_config.pipe_info[vi_pipe].pipe_no = vi_pipe;
|
|
vi_config.pipe_info[vi_pipe].chn_info[vi_chn].chn_en = XMEDIA_TRUE;
|
|
vi_config.pipe_info[vi_pipe].chn_info[vi_chn].chn_no = vi_chn;
|
|
vi_config.dev_bind_pipe[vi_dev].pipe[0] = vi_pipe;
|
|
vi_config.dev_bind_pipe[vi_dev].pipe[1] = -1;
|
|
|
|
isp_config.fps = framerate;
|
|
isp_config.mode_config.work_mode = XMEDIA_ISP_WORK_MODE_MASTER;
|
|
isp_config.mode_config.master_mode.blend_stat_enable = XMEDIA_FALSE;
|
|
isp_config.mode_config.master_mode.slave_num = 0;
|
|
isp_config.pixel_fmt = sensor_info.pixel_format;
|
|
isp_config.size.height = sensor_info.height;
|
|
isp_config.size.width = sensor_info.width;
|
|
isp_config.wdr_mode = sensor_info.wdr_mode;
|
|
|
|
// isp pipe init
|
|
isp_param.pipe[vi_pipe] = vi_pipe;
|
|
isp_param.isp_info[vi_pipe].isp_pipe_en = XMEDIA_TRUE;
|
|
isp_param.isp_info[vi_pipe].isp_sensor_en = XMEDIA_TRUE;
|
|
isp_param.isp_info[vi_pipe].sensor_type = sensor_type;
|
|
isp_param.isp_info[vi_pipe].mirror = mirror;
|
|
isp_param.isp_info[vi_pipe].flip = flip;
|
|
memcpy(&(isp_param.isp_info[vi_pipe].isp_config), &isp_config, sizeof(xmedia_isp_config));
|
|
|
|
// isp init
|
|
ret = sample_comm_isp_init(&isp_param, &vi_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("isp init failed!\n");
|
|
goto exit0;
|
|
}
|
|
|
|
// vi start
|
|
ret = sample_comm_vi_start(&vi_config, &video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("start vi failed!\n");
|
|
goto exit1;
|
|
}
|
|
|
|
// isp start
|
|
ret = sample_comm_isp_start(&isp_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("start isp failed!\n");
|
|
goto exit2;
|
|
}
|
|
|
|
// vpss config
|
|
ret = sample_comm_vpss_get_default_pipe_cfg(&vpss_config.pipe_info[vpss_pipe].pipe_config, pic_size, &video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("get default pipe cfg failed !\n");
|
|
goto exit2;
|
|
}
|
|
|
|
vpss_ochn_size[0].width = sensor_info.width;
|
|
vpss_ochn_size[0].height = sensor_info.height;
|
|
|
|
vpss_config.pipe_info[vpss_pipe].pipe_en = XMEDIA_TRUE;
|
|
vpss_config.pipe_info[vpss_pipe].pipe_no = vpss_pipe;
|
|
|
|
vpss_chnl = vpss_ochn[0];
|
|
vpss_config.pipe_info[vpss_pipe].chn_info[vpss_chnl].chn_en = XMEDIA_TRUE;
|
|
vpss_config.pipe_info[vpss_pipe].chn_info[vpss_chnl].chn_no = vpss_ochn[0];
|
|
ret = sample_comm_vpss_get_default_ochn_cfg(&vpss_config.pipe_info[vpss_pipe].chn_info[vpss_chnl].chn_config,
|
|
vpss_ochn_size[vpss_chnl], &video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("get default pipe cfg failed !\n");
|
|
goto exit2;
|
|
}
|
|
vpss_config.pipe_info[vpss_pipe].chn_info[vpss_chnl].chn_config.depth = 0;
|
|
|
|
// vpss start
|
|
ret = sample_comm_vpss_start(&vpss_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("vpss start failed !\n");
|
|
goto exit2;
|
|
}
|
|
|
|
ret = sample_comm_sys_vi_bind_vpss(vi_pipe, vi_chn, vpss_pipe, vpss_ichn);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("vi bind vpss failed !\n");
|
|
goto exit3;
|
|
}
|
|
|
|
venc_chnl = venc_chn[0];
|
|
venc_config.chn_info[venc_chnl].venc_en = XMEDIA_TRUE;
|
|
venc_config.chn_info[venc_chnl].venc_chn = venc_chnl;
|
|
venc_config.chn_info[venc_chnl].payload_type = PT_H265;
|
|
venc_config.chn_info[venc_chnl].rc_mode = VENC_RC_MODE_H265CBR;
|
|
venc_config.chn_info[venc_chnl].venc_gop_attr.gop_mode = gop_mode;
|
|
sample_comm_venc_get_default_chn_info(vpss_ochn_size[0], framerate, &venc_config.chn_info[venc_chnl]);
|
|
|
|
ret = sample_comm_venc_start(&venc_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("venc start failed !\n");
|
|
goto exit4;
|
|
}
|
|
|
|
if (set_roi == XMEDIA_TRUE) {
|
|
ret = sample_comm_venc_set_roi(venc_chn, venc_chn_cnt);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("venc start get stream failed !\n");
|
|
goto exit4;
|
|
}
|
|
}
|
|
|
|
ret = sample_comm_sys_vpss_bind_venc(vpss_pipe, vpss_ochn[0], venc_chn[0]);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("vpss bind venc failed !\n");
|
|
goto exit5;
|
|
}
|
|
|
|
sample_msensor_start_dump_data(msensor_dev);
|
|
|
|
PAUSE(g_force_exit);
|
|
|
|
sample_msensor_stop_dump_data(msensor_dev);
|
|
|
|
sample_comm_sys_vpss_unbind_venc(vpss_pipe, vpss_ochn[0], venc_chn[0]);
|
|
exit5:
|
|
sample_comm_venc_stop(&venc_config);
|
|
exit4:
|
|
sample_comm_sys_vi_unbind_vpss(vi_pipe, vi_chn, vpss_pipe, vpss_ichn);
|
|
exit3:
|
|
sample_comm_vpss_stop(&vpss_config);
|
|
exit2:
|
|
sample_comm_isp_stop(&isp_param);
|
|
exit1:
|
|
sample_comm_vi_stop(&vi_config);
|
|
exit0:
|
|
sample_comm_isp_exit(&isp_param);
|
|
sample_msensor_exit(1, &msensor_dev);
|
|
sample_msensor_sys_exit();
|
|
|
|
return ret;
|
|
}
|
|
|
|
int main(int argc,char **argv)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_SUCCESS;
|
|
xmedia_s32 index = 0;
|
|
xmedia_bool set_roi = XMEDIA_FALSE;
|
|
|
|
signal(SIGINT, sample_msensor_handle_sig);
|
|
signal(SIGTERM, sample_msensor_handle_sig);
|
|
|
|
if (argc < 2) {
|
|
sample_msensor_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
index = atoi(argv[1]);
|
|
if (argc == 2) {
|
|
switch (index) {
|
|
case 0:
|
|
ret = sample_venc_h265_msensor(set_roi);
|
|
break;
|
|
case 1:
|
|
sample_msensor_parse_data();
|
|
break;
|
|
default:
|
|
sample_msensor_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (XMEDIA_SUCCESS == ret) {
|
|
SAMPLE_PRT("program exit normally!\n");
|
|
} else {
|
|
SAMPLE_PRT("program exit abnormally!\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|