project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp: Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem. sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately. sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades. sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for fastboot. Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
1035 lines
32 KiB
C
1035 lines
32 KiB
C
/*
|
|
* Copyright 2023 Rockchip Electronics Co. LTD
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
#endif /* End of #ifdef __cplusplus */
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <getopt.h>
|
|
#include <pthread.h>
|
|
#include <signal.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/prctl.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
#include "rk_aiq.h"
|
|
#include "rk_aiq_mems_sensor.h"
|
|
#include "rkiio.h"
|
|
#include "rtsp_demo.h"
|
|
#include "sample_comm.h"
|
|
#include "uAPI/rk_aiq_user_api_sysctl.h"
|
|
|
|
#define BUFFER_SIZE 255
|
|
#define VI_CHN_MAX 3
|
|
#define VENC_CHN_MAX 4
|
|
|
|
typedef struct _rkThreadStatus {
|
|
RK_BOOL bIfMainThreadQuit;
|
|
} ThreadStatus;
|
|
|
|
/* global param */
|
|
ThreadStatus *gPThreadStatus = RK_NULL;
|
|
RK_S32 g_exit_result = RK_SUCCESS;
|
|
pthread_mutex_t g_rtsp_mutex = {0};
|
|
RK_BOOL g_rtsp_ifenbale = RK_FALSE;
|
|
rtsp_demo_handle g_rtsplive = RK_NULL;
|
|
static rtsp_session_handle g_rtsp_session[4] = {0};
|
|
|
|
typedef struct _rkMpiCtx {
|
|
SAMPLE_VI_CTX_S vi;
|
|
SAMPLE_VENC_CTX_S venc;
|
|
} SAMPLE_MPI_CTX_S;
|
|
|
|
static void program_handle_error(const char *func, RK_U32 line) {
|
|
RK_LOGE("func: <%s> line: <%d> error exit!", func, line);
|
|
g_exit_result = RK_FAILURE;
|
|
gPThreadStatus->bIfMainThreadQuit = RK_TRUE;
|
|
}
|
|
|
|
static void program_normal_exit(const char *func, RK_U32 line) {
|
|
RK_LOGE("func: <%s> line: <%d> normal exit!", func, line);
|
|
gPThreadStatus->bIfMainThreadQuit = RK_TRUE;
|
|
}
|
|
|
|
static void sigterm_handler(int sig) {
|
|
fprintf(stderr, "signal %d\n", sig);
|
|
program_normal_exit(__func__, __LINE__);
|
|
}
|
|
|
|
static RK_CHAR optstr[] = "?::a::d:c:f:w:h:e:o:I:l:m:";
|
|
static const struct option long_options[] = {
|
|
{"aiq", optional_argument, NULL, 'a'},
|
|
{"device_name", required_argument, NULL, 'd'},
|
|
{"chn_id", required_argument, NULL, 'c'},
|
|
{"pixel_format", optional_argument, NULL, 'f'},
|
|
{"width", required_argument, NULL, 'w'},
|
|
{"height", required_argument, NULL, 'h'},
|
|
{"eis_mode", required_argument, NULL, 'e'},
|
|
{"output_path", required_argument, NULL, 'o'},
|
|
{"camid", required_argument, NULL, 'I'},
|
|
{"loop_count", required_argument, NULL, 'l'},
|
|
{"hdr_mode", required_argument, NULL, 'h' + 'm'},
|
|
{"help", optional_argument, NULL, '?'},
|
|
{NULL, 0, NULL, 0},
|
|
};
|
|
|
|
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static bool g_init_flag = false;
|
|
static uint32_t g_sensor_cnt = 0;
|
|
static uint32_t g_handle_cnt = 0;
|
|
|
|
typedef struct rkiio_sensor_ctx_s {
|
|
uint64_t ctx_id;
|
|
} rkiio_sensor_ctx_t;
|
|
|
|
typedef struct rkiio_sensor_handle_buf_s {
|
|
pthread_mutex_t buf_mutex;
|
|
bool is_valid;
|
|
void *buf;
|
|
} rkiio_sensor_handle_buf_t;
|
|
|
|
typedef struct rkiio_sensor_handle_ctx_s {
|
|
mems_sensor_type_t sensor_type;
|
|
RKIIO_DATA_HANDLE handle;
|
|
uint32_t max_data_num;
|
|
uint32_t buf_cnt;
|
|
rkiio_sensor_handle_buf_t *buf_pool;
|
|
pthread_mutex_t fifo_buf_mutex;
|
|
RKIIO_FIFO_DATA fifo_data_buf;
|
|
} rkiio_sensor_handle_t;
|
|
|
|
static mems_sensor_ctx_t rkiio_aiq_sensor_ctx_create() {
|
|
pthread_mutex_lock(&g_mutex);
|
|
g_sensor_cnt++;
|
|
if (!g_init_flag) {
|
|
rkiio_sys_init();
|
|
rkiio_timestamp_type_set_all(RKIIO_TIMESTAMP_MONOTONIC);
|
|
}
|
|
g_init_flag = true;
|
|
pthread_mutex_unlock(&g_mutex);
|
|
rkiio_sensor_ctx_t *ctx = (rkiio_sensor_ctx_t *)malloc(sizeof(rkiio_sensor_ctx_t));
|
|
memset(ctx, 0, sizeof(rkiio_sensor_ctx_t));
|
|
return (mems_sensor_ctx_t)ctx;
|
|
}
|
|
|
|
static mems_sensor_return_t rkiio_aiq_sensor_ctx_destroy(mems_sensor_ctx_t ctx) {
|
|
if (!ctx) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
rkiio_sensor_ctx_t *rkiio_ctx = (rkiio_sensor_ctx_t *)ctx;
|
|
free(rkiio_ctx);
|
|
pthread_mutex_lock(&g_mutex);
|
|
g_sensor_cnt--;
|
|
if (!g_sensor_cnt) {
|
|
rkiio_sys_uninit();
|
|
g_init_flag = false;
|
|
}
|
|
pthread_mutex_unlock(&g_mutex);
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
static mems_sensor_return_t rkiio_aiq_sensors_list_get(mems_sensor_ctx_t ctx,
|
|
mems_sensor_type_t sensor_type,
|
|
mems_sensor_list_t *sensors_list) {
|
|
if (!g_init_flag) {
|
|
return SENSOR_ERR_FAIL;
|
|
}
|
|
if (!sensors_list || !ctx) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
switch (sensor_type) {
|
|
case SENSOR_GRYO_TYPE:
|
|
sensors_list->key_list = rkiio_anglvel_dev_list_get(&sensors_list->count);
|
|
break;
|
|
case SENSOR_ACCEL_TYPE:
|
|
sensors_list->key_list = rkiio_accel_dev_list_get(&sensors_list->count);
|
|
break;
|
|
case SENSOR_TEMP_TYPE:
|
|
sensors_list->key_list = rkiio_temp_dev_list_get(&sensors_list->count);
|
|
break;
|
|
case SENSOR_ALL_TYPE:
|
|
sensors_list->key_list = rkiio_all_dev_list_get(&sensors_list->count);
|
|
break;
|
|
default:
|
|
return SENSOR_ERR_MISMATCH_SENSOR;
|
|
}
|
|
if (sensors_list->count) {
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
return SENSOR_ERR_MISMATCH_SENSOR;
|
|
}
|
|
|
|
static mems_sensor_return_t
|
|
rkiio_aiq_sensors_list_release(mems_sensor_list_t *sensors_list) {
|
|
if (!sensors_list) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
int32_t ret = rkiio_dev_list_destroy(sensors_list->key_list, sensors_list->count);
|
|
if (ret) {
|
|
return SENSOR_ERR_FAIL;
|
|
}
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
static mems_sensor_return_t rkiio_aiq_sensor_cap_get(mems_sensor_ctx_t ctx,
|
|
mems_sensor_type_t sensor_type,
|
|
char *sensor_key,
|
|
mems_sensor_capabilities_t *caps) {
|
|
if (!g_init_flag) {
|
|
return SENSOR_ERR_FAIL;
|
|
}
|
|
if (!ctx) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
memset(caps, 0, sizeof(mems_sensor_capabilities_t));
|
|
caps->type = sensor_type;
|
|
switch (sensor_type) {
|
|
case SENSOR_GRYO_TYPE:
|
|
rkiio_sampling_rate_cap_get(sensor_key, RKIIO_SENSOR_ANGLVEL_TYPE,
|
|
&(caps->sample_rates), &(caps->num_sample_rates));
|
|
break;
|
|
case SENSOR_ACCEL_TYPE:
|
|
rkiio_sampling_rate_cap_get(sensor_key, RKIIO_SENSOR_ACCEL_TYPE,
|
|
&(caps->sample_rates), &(caps->num_sample_rates));
|
|
break;
|
|
case SENSOR_TEMP_TYPE:
|
|
rkiio_sampling_rate_cap_get(sensor_key, RKIIO_SENSOR_TEMP_TYPE,
|
|
&(caps->sample_rates), &(caps->num_sample_rates));
|
|
break;
|
|
case SENSOR_ALL_TYPE:
|
|
rkiio_sampling_rate_cap_get(sensor_key, RKIIO_SENSOR_ALL_TYPE,
|
|
&(caps->sample_rates), &(caps->num_sample_rates));
|
|
break;
|
|
default:
|
|
return SENSOR_ERR_MISMATCH_SENSOR;
|
|
}
|
|
caps->is_data_valid = true;
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
static mems_sensor_return_t
|
|
rkiio_aiq_sensor_cap_release(mems_sensor_capabilities_t *caps) {
|
|
if (caps->sample_rates)
|
|
rkiio_sampling_rate_cap_release(caps->sample_rates);
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
// only support sampling rate
|
|
static mems_sensor_return_t rkiio_aiq_sensor_config_get(mems_sensor_ctx_t ctx,
|
|
mems_sensor_type_t sensor_type,
|
|
char *sensor_key,
|
|
mems_sensor_config_t *cfg) {
|
|
if (!g_init_flag) {
|
|
return SENSOR_ERR_FAIL;
|
|
}
|
|
if (!cfg || !ctx) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
if (g_handle_cnt) {
|
|
return SENSOR_ERR_DEV_BUSY;
|
|
}
|
|
memset(cfg, 0, sizeof(mems_sensor_config_t));
|
|
int32_t ret = 0;
|
|
switch (sensor_type) {
|
|
case SENSOR_GRYO_TYPE:
|
|
ret = rkiio_sampling_rate_get(sensor_key, RKIIO_SENSOR_ANGLVEL_TYPE,
|
|
&(cfg->sample_rate));
|
|
break;
|
|
case SENSOR_ACCEL_TYPE:
|
|
ret = rkiio_sampling_rate_get(sensor_key, RKIIO_SENSOR_ACCEL_TYPE,
|
|
&(cfg->sample_rate));
|
|
break;
|
|
case SENSOR_TEMP_TYPE:
|
|
ret = rkiio_sampling_rate_get(sensor_key, RKIIO_SENSOR_TEMP_TYPE,
|
|
&(cfg->sample_rate));
|
|
break;
|
|
case SENSOR_ALL_TYPE:
|
|
ret = rkiio_sampling_rate_get(sensor_key, RKIIO_SENSOR_ALL_TYPE,
|
|
&(cfg->sample_rate));
|
|
break;
|
|
default:
|
|
return SENSOR_ERR_MISMATCH_SENSOR;
|
|
}
|
|
if (ret) {
|
|
cfg->sample_rate = 0.0f;
|
|
return SENSOR_ERR_FAIL;
|
|
}
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
static mems_sensor_return_t rkiio_aiq_sensor_config_set(mems_sensor_ctx_t ctx,
|
|
mems_sensor_type_t sensor_type,
|
|
char *sensor_key,
|
|
mems_sensor_config_t cfg) {
|
|
if (!g_init_flag) {
|
|
return SENSOR_ERR_FAIL;
|
|
}
|
|
if (!ctx) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
if (g_handle_cnt) {
|
|
return SENSOR_ERR_DEV_BUSY;
|
|
}
|
|
int32_t ret = 0;
|
|
switch (sensor_type) {
|
|
case SENSOR_GRYO_TYPE:
|
|
ret = rkiio_sampling_rate_set(sensor_key, RKIIO_SENSOR_ANGLVEL_TYPE,
|
|
cfg.sample_rate);
|
|
break;
|
|
case SENSOR_ACCEL_TYPE:
|
|
ret =
|
|
rkiio_sampling_rate_set(sensor_key, RKIIO_SENSOR_ACCEL_TYPE, cfg.sample_rate);
|
|
break;
|
|
case SENSOR_TEMP_TYPE:
|
|
ret =
|
|
rkiio_sampling_rate_set(sensor_key, RKIIO_SENSOR_TEMP_TYPE, cfg.sample_rate);
|
|
break;
|
|
case SENSOR_ALL_TYPE:
|
|
ret = rkiio_sampling_rate_set(sensor_key, RKIIO_SENSOR_ALL_TYPE, cfg.sample_rate);
|
|
break;
|
|
default:
|
|
return SENSOR_ERR_MISMATCH_SENSOR;
|
|
}
|
|
if (ret) {
|
|
return SENSOR_ERR_FAIL;
|
|
}
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
static uint32_t _rkiio_aiq_buf_id_get(void *buf, uint32_t max_data_num) {
|
|
uint8_t *data = (uint8_t *)buf;
|
|
uint64_t idx = sizeof(mems_sensor_event_t) * max_data_num;
|
|
int32_t *reserverd_data = (int32_t *)&(data[idx]);
|
|
return *reserverd_data;
|
|
}
|
|
|
|
static void _rkiio_aiq_buf_id_set(void *buf, uint32_t max_data_num, uint32_t id) {
|
|
uint8_t *data = (uint8_t *)buf;
|
|
uint64_t idx = sizeof(mems_sensor_event_t) * max_data_num;
|
|
int32_t *reserverd_data = (int32_t *)&(data[idx]);
|
|
*reserverd_data = id;
|
|
}
|
|
|
|
static mems_sensor_handle_t rkiio_aiq_sensor_handle_create(mems_sensor_ctx_t ctx,
|
|
mems_sensor_type_t sensor_type,
|
|
char *sensor_key,
|
|
uint32_t max_data_num,
|
|
uint32_t buf_cnt) {
|
|
if (!g_init_flag || !ctx || !max_data_num || !buf_cnt) {
|
|
return NULL;
|
|
}
|
|
rkiio_sensor_handle_t *sensor_handle =
|
|
(rkiio_sensor_handle_t *)malloc(sizeof(rkiio_sensor_handle_t));
|
|
memset(sensor_handle, 0, sizeof(rkiio_sensor_handle_t));
|
|
sensor_handle->sensor_type = sensor_type;
|
|
sensor_handle->buf_cnt = buf_cnt;
|
|
|
|
sensor_handle->handle = rkiio_data_handle_create(sensor_key, 0, max_data_num);
|
|
uint32_t real_max_data_num = 0;
|
|
rkiio_data_handle_max_fifo_num_get(sensor_handle->handle, &real_max_data_num);
|
|
sensor_handle->max_data_num =
|
|
(max_data_num > real_max_data_num) ? max_data_num : real_max_data_num;
|
|
|
|
pthread_mutex_init(&(sensor_handle->fifo_buf_mutex), NULL);
|
|
sensor_handle->fifo_data_buf =
|
|
(RKIIO_FIFO_DATA)malloc(sizeof(rkiio_data_0_t) * sensor_handle->max_data_num);
|
|
|
|
sensor_handle->buf_pool =
|
|
(rkiio_sensor_handle_buf_t *)malloc(sizeof(rkiio_sensor_handle_buf_t) * buf_cnt);
|
|
memset(sensor_handle->buf_pool, 0, sizeof(rkiio_sensor_handle_buf_t) * buf_cnt);
|
|
for (uint32_t i = 0; i < buf_cnt; i++) {
|
|
pthread_mutex_init(&(sensor_handle->buf_pool[i].buf_mutex), NULL);
|
|
sensor_handle->buf_pool[i].is_valid = true;
|
|
sensor_handle->buf_pool[i].buf = (void *)malloc(
|
|
sizeof(mems_sensor_event_t) * sensor_handle->max_data_num + sizeof(uint32_t));
|
|
memset(sensor_handle->buf_pool[i].buf, 0,
|
|
sizeof(mems_sensor_event_t) * sensor_handle->max_data_num +
|
|
sizeof(uint32_t));
|
|
_rkiio_aiq_buf_id_set(sensor_handle->buf_pool[i].buf, sensor_handle->max_data_num,
|
|
i);
|
|
}
|
|
pthread_mutex_lock(&g_mutex);
|
|
g_handle_cnt++;
|
|
pthread_mutex_unlock(&g_mutex);
|
|
return (mems_sensor_handle_t)sensor_handle;
|
|
}
|
|
|
|
static mems_sensor_return_t rkiio_aiq_sensor_handle_destroy(mems_sensor_handle_t handle) {
|
|
if (!handle) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
rkiio_sensor_handle_t *sensor_handle = (rkiio_sensor_handle_t *)handle;
|
|
pthread_mutex_lock(&(sensor_handle->fifo_buf_mutex));
|
|
rkiio_data_handle_destroy(sensor_handle->handle);
|
|
if (sensor_handle->fifo_data_buf)
|
|
free(sensor_handle->fifo_data_buf);
|
|
if (sensor_handle->buf_pool) {
|
|
for (uint32_t i = 0; i < sensor_handle->buf_cnt; i++) {
|
|
if (sensor_handle->buf_pool[i].buf)
|
|
free(sensor_handle->buf_pool[i].buf);
|
|
}
|
|
free(sensor_handle->buf_pool);
|
|
}
|
|
pthread_mutex_unlock(&(sensor_handle->fifo_buf_mutex));
|
|
free(sensor_handle);
|
|
pthread_mutex_lock(&g_mutex);
|
|
g_handle_cnt--;
|
|
pthread_mutex_unlock(&g_mutex);
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
static uint32_t _rkiio_aiq_get_vaild_buf(rkiio_sensor_handle_t *handle) {
|
|
while (1) {
|
|
for (uint32_t i = 0; i < handle->buf_cnt; i++) {
|
|
pthread_mutex_lock(&(handle->buf_pool[i].buf_mutex));
|
|
// printf("%s: id: %u, valid: %d\n", __FUNCTION__, i,
|
|
// handle->buf_pool[i].is_valid);
|
|
if (handle->buf_pool[i].is_valid) {
|
|
handle->buf_pool[i].is_valid = false;
|
|
pthread_mutex_unlock(&(handle->buf_pool[i].buf_mutex));
|
|
return i;
|
|
}
|
|
pthread_mutex_unlock(&(handle->buf_pool[i].buf_mutex));
|
|
}
|
|
usleep(100000);
|
|
}
|
|
}
|
|
|
|
static mems_sensor_data_t _rkiio_aiq_getData_gyro(rkiio_sensor_handle_t *handle,
|
|
uint64_t data_num) {
|
|
rkiio_data_0_t *fifo = (rkiio_data_0_t *)handle->fifo_data_buf;
|
|
uint32_t valid_id = _rkiio_aiq_get_vaild_buf(handle);
|
|
mems_sensor_event_t *event = (mems_sensor_event_t *)(handle->buf_pool[valid_id].buf);
|
|
memset(event, 0, sizeof(mems_sensor_event_t) * data_num);
|
|
for (uint64_t i = 0; i < data_num; i++) {
|
|
memcpy(&(event[i].gyro), &(fifo[i].anglvel), sizeof(xyz_data_t));
|
|
event[i].timestamp_us = fifo[i].timestamp;
|
|
event[i].id = fifo[i].id;
|
|
// printf("%llu:, x: %f, y: %f, z: %f, t: %llu, %llu:, x: %f, y: %f, z: %f, t:
|
|
// %llu\n",
|
|
// fifo[i].id, fifo[i].anglvel.x, fifo[i].anglvel.y, fifo[i].anglvel.z,
|
|
// fifo[i].timestamp, event[i].id, event[i].gyro.x, event[i].gyro.y,
|
|
// event[i].gyro.z, event[i].timestamp_us);
|
|
}
|
|
return (mems_sensor_data_t)event;
|
|
}
|
|
|
|
static mems_sensor_data_t _rkiio_aiq_getData_accel(rkiio_sensor_handle_t *handle,
|
|
uint64_t data_num) {
|
|
rkiio_data_0_t *fifo = (rkiio_data_0_t *)handle->fifo_data_buf;
|
|
uint32_t valid_id = _rkiio_aiq_get_vaild_buf(handle);
|
|
mems_sensor_event_t *event = (mems_sensor_event_t *)(handle->buf_pool[valid_id].buf);
|
|
memset(event, 0, sizeof(mems_sensor_event_t) * data_num);
|
|
for (uint64_t i = 0; i < data_num; i++) {
|
|
memcpy(&(event[i].accel), &(fifo[i].accel), sizeof(xyz_data_t));
|
|
event[i].timestamp_us = fifo[i].timestamp;
|
|
event[i].id = fifo[i].id;
|
|
}
|
|
return (mems_sensor_data_t)event;
|
|
}
|
|
|
|
static mems_sensor_data_t _rkiio_aiq_getData_temp(rkiio_sensor_handle_t *handle,
|
|
uint64_t data_num) {
|
|
rkiio_data_0_t *fifo = (rkiio_data_0_t *)handle->fifo_data_buf;
|
|
uint32_t valid_id = _rkiio_aiq_get_vaild_buf(handle);
|
|
mems_sensor_event_t *event = (mems_sensor_event_t *)(handle->buf_pool[valid_id].buf);
|
|
memset(event, 0, sizeof(mems_sensor_event_t) * data_num);
|
|
for (uint64_t i = 0; i < data_num; i++) {
|
|
// temp alter to s32?
|
|
event[i].temperature = fifo[i].temp;
|
|
event[i].timestamp_us = fifo[i].timestamp;
|
|
event[i].id = fifo[i].id;
|
|
}
|
|
return (mems_sensor_data_t)event;
|
|
}
|
|
|
|
static mems_sensor_data_t _rkiio_aiq_getData_all(rkiio_sensor_handle_t *handle,
|
|
uint64_t data_num) {
|
|
rkiio_data_0_t *fifo = (rkiio_data_0_t *)handle->fifo_data_buf;
|
|
uint32_t valid_id = _rkiio_aiq_get_vaild_buf(handle);
|
|
mems_sensor_event_t *event = (mems_sensor_event_t *)(handle->buf_pool[valid_id].buf);
|
|
memset(event, 0, sizeof(mems_sensor_event_t) * data_num);
|
|
for (uint64_t i = 0; i < data_num; i++) {
|
|
memcpy(&(event[i].all.gyro), &(fifo[i].anglvel), sizeof(xyz_data_t));
|
|
memcpy(&(event[i].all.accel), &(fifo[i].accel), sizeof(xyz_data_t));
|
|
// temp alter to s32?
|
|
event[i].all.temperature = fifo[i].temp;
|
|
event[i].timestamp_us = fifo[i].timestamp;
|
|
event[i].id = fifo[i].id;
|
|
}
|
|
return (mems_sensor_data_t)event;
|
|
}
|
|
|
|
static mems_sensor_data_t rkiio_aiq_getData(mems_sensor_handle_t handle,
|
|
size_t *num_samples) {
|
|
if (!handle) {
|
|
return NULL;
|
|
}
|
|
int32_t ret = 0;
|
|
rkiio_sensor_handle_t *sensor_handle = (rkiio_sensor_handle_t *)handle;
|
|
pthread_mutex_lock(&(sensor_handle->fifo_buf_mutex));
|
|
uint64_t data_num = 0;
|
|
ret = rkiio_data_get_all(sensor_handle->handle, sensor_handle->fifo_data_buf,
|
|
&data_num);
|
|
if (ret || !data_num) {
|
|
*num_samples = 0;
|
|
pthread_mutex_unlock(&(sensor_handle->fifo_buf_mutex));
|
|
return NULL;
|
|
}
|
|
mems_sensor_data_t data = NULL;
|
|
switch (sensor_handle->sensor_type) {
|
|
case SENSOR_GRYO_TYPE:
|
|
data = _rkiio_aiq_getData_gyro(sensor_handle, data_num);
|
|
break;
|
|
case SENSOR_ACCEL_TYPE:
|
|
data = _rkiio_aiq_getData_accel(sensor_handle, data_num);
|
|
break;
|
|
case SENSOR_TEMP_TYPE:
|
|
data = _rkiio_aiq_getData_temp(sensor_handle, data_num);
|
|
break;
|
|
case SENSOR_ALL_TYPE:
|
|
data = _rkiio_aiq_getData_all(sensor_handle, data_num);
|
|
break;
|
|
default:
|
|
data = NULL;
|
|
}
|
|
*num_samples = data ? (size_t)data_num : 0;
|
|
pthread_mutex_unlock(&(sensor_handle->fifo_buf_mutex));
|
|
return data;
|
|
}
|
|
|
|
static mems_sensor_data_t rkiio_aiq_getLastNSamples(mems_sensor_handle_t handle,
|
|
size_t num_samples) {
|
|
if (!handle || !num_samples) {
|
|
return NULL;
|
|
}
|
|
rkiio_sensor_handle_t *sensor_handle = (rkiio_sensor_handle_t *)handle;
|
|
if ((uint32_t)num_samples > sensor_handle->max_data_num) {
|
|
printf("%s: num_samples > max_data_num\n", __FUNCTION__);
|
|
return NULL;
|
|
}
|
|
int32_t ret = 0;
|
|
pthread_mutex_lock(&(sensor_handle->fifo_buf_mutex));
|
|
uint64_t data_num = (uint64_t)num_samples;
|
|
ret = rkiio_data_read(sensor_handle->handle, sensor_handle->fifo_data_buf, data_num);
|
|
if (ret) {
|
|
pthread_mutex_unlock(&(sensor_handle->fifo_buf_mutex));
|
|
return NULL;
|
|
}
|
|
mems_sensor_data_t data = NULL;
|
|
switch (sensor_handle->sensor_type) {
|
|
case SENSOR_GRYO_TYPE:
|
|
data = _rkiio_aiq_getData_gyro(sensor_handle, data_num);
|
|
break;
|
|
case SENSOR_ACCEL_TYPE:
|
|
data = _rkiio_aiq_getData_accel(sensor_handle, data_num);
|
|
break;
|
|
case SENSOR_TEMP_TYPE:
|
|
data = _rkiio_aiq_getData_temp(sensor_handle, data_num);
|
|
break;
|
|
case SENSOR_ALL_TYPE:
|
|
data = _rkiio_aiq_getData_all(sensor_handle, data_num);
|
|
break;
|
|
default:
|
|
data = NULL;
|
|
}
|
|
pthread_mutex_unlock(&(sensor_handle->fifo_buf_mutex));
|
|
return data;
|
|
}
|
|
|
|
static mems_sensor_return_t
|
|
rkiio_aiq_sensor_data_release(mems_sensor_handle_t sensor_handle,
|
|
mems_sensor_data_t data) {
|
|
if (!data || !sensor_handle) {
|
|
return SENSOR_ERR_NULL_PTR;
|
|
}
|
|
rkiio_sensor_handle_t *handle = (rkiio_sensor_handle_t *)sensor_handle;
|
|
uint32_t idx = _rkiio_aiq_buf_id_get(data, handle->max_data_num);
|
|
pthread_mutex_lock(&(handle->buf_pool[idx].buf_mutex));
|
|
handle->buf_pool[idx].is_valid = true;
|
|
pthread_mutex_unlock(&(handle->buf_pool[idx].buf_mutex));
|
|
return SENSOR_NO_ERR;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* function : show usage
|
|
******************************************************************************/
|
|
static void print_usage(const RK_CHAR *name) {
|
|
printf("usage example:\n");
|
|
printf("\t%s -w 1296 -h 972 -a /etc/iqfiles/ -e 1\n", name);
|
|
#ifdef RKAIQ
|
|
printf("\t-a | --aiq: enable aiq with dirpath provided, eg:-a /etc/iqfiles/, "
|
|
"set dirpath empty to using path by default, without this option aiq "
|
|
"should run in other application\n");
|
|
#endif
|
|
printf("\t-d | --device_name: set pcDeviceName, eg: /dev/video0 Default "
|
|
"NULL\n");
|
|
printf("\t-c | --chn_id: channel id, default: 1\n");
|
|
printf("\t-f | --pixel_format: camera Format, Default nv12, "
|
|
"Value:nv12,nv16,uyvy,yuyv.\n");
|
|
printf("\t-w | --width: camera with, Default 1296\n");
|
|
printf("\t-h | --height: camera height, Default 972\n");
|
|
printf("\t-e | --eis_mode: set EIS(Electric Image Stabilization) mode, "
|
|
"0: close, 1: enable eis, Default: 1\n");
|
|
printf("\t-o | --output_path: vi output file path, Default NULL\n");
|
|
printf("\t-I | --camid: camera ctx id, Default 0\n");
|
|
printf("\t-l | --loop_count: loop count, Default -1\n");
|
|
printf("\t--hdr_mode: set hdr mode, 0: normal 1: HDR2, 2: HDR3, Default: 0\n");
|
|
}
|
|
|
|
static void *venc_get_stream(void *pArgs) {
|
|
|
|
SAMPLE_VENC_CTX_S *ctx = (SAMPLE_VENC_CTX_S *)pArgs;
|
|
RK_S32 s32Ret = RK_FAILURE;
|
|
FILE *fp = RK_NULL;
|
|
RK_S32 s32fd = 0;
|
|
RK_S32 loopCount = 0;
|
|
RK_VOID *pData = RK_NULL;
|
|
RK_CHAR name[BUFFER_SIZE] = {0};
|
|
sprintf(name, "venc_%d_get_stream", ctx->s32ChnId);
|
|
prctl(PR_SET_NAME, name);
|
|
|
|
if (ctx->dstFilePath) {
|
|
memset(name, 0, BUFFER_SIZE);
|
|
snprintf(name, sizeof(name), "/%s/venc_%d.bin", ctx->dstFilePath, ctx->s32ChnId);
|
|
fp = fopen(name, "wb");
|
|
if (fp == RK_NULL) {
|
|
RK_LOGE("chn %d can't open %s file !\n", ctx->s32ChnId, ctx->dstFilePath);
|
|
program_handle_error(__func__, __LINE__);
|
|
return RK_NULL;
|
|
}
|
|
s32fd = fileno(fp);
|
|
}
|
|
while (!gPThreadStatus->bIfMainThreadQuit) {
|
|
s32Ret = SAMPLE_COMM_VENC_GetStream(ctx, &pData);
|
|
if (s32Ret == RK_SUCCESS) {
|
|
|
|
if (ctx->s32loopCount > 0) {
|
|
if (loopCount >= ctx->s32loopCount) {
|
|
SAMPLE_COMM_VENC_ReleaseStream(ctx);
|
|
program_normal_exit(__func__, __LINE__);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fp && !gPThreadStatus->bIfMainThreadQuit) {
|
|
fwrite(pData, 1, ctx->stFrame.pstPack->u32Len, fp);
|
|
fflush(fp);
|
|
}
|
|
if (g_rtsp_ifenbale) {
|
|
pthread_mutex_lock(&g_rtsp_mutex);
|
|
rtsp_tx_video(g_rtsp_session[ctx->s32ChnId], pData,
|
|
ctx->stFrame.pstPack->u32Len, ctx->stFrame.pstPack->u64PTS);
|
|
rtsp_do_event(g_rtsplive);
|
|
pthread_mutex_unlock(&g_rtsp_mutex);
|
|
} else {
|
|
RK_LOGD("venc %d get_stream count: %d", ctx->s32ChnId, loopCount);
|
|
}
|
|
|
|
RK_LOGD("venc %d get_stream count: %d", ctx->s32ChnId, loopCount);
|
|
|
|
SAMPLE_COMM_VENC_ReleaseStream(ctx);
|
|
loopCount++;
|
|
}
|
|
}
|
|
|
|
if (fp) {
|
|
fsync(s32fd);
|
|
fclose(fp);
|
|
}
|
|
|
|
RK_LOGE("venc_get_stream chnid:%d exit", ctx->s32ChnId);
|
|
return RK_NULL;
|
|
}
|
|
|
|
static RK_S32 rtsp_init(CODEC_TYPE_E enCodecType) {
|
|
RK_S32 i = 0;
|
|
g_rtsplive = create_rtsp_demo(554);
|
|
RK_CHAR rtspAddr[BUFFER_SIZE] = {0};
|
|
|
|
for (i = 0; i < VENC_CHN_MAX; i++) {
|
|
|
|
sprintf(rtspAddr, "/live/%d", i);
|
|
g_rtsp_session[i] = rtsp_new_session(g_rtsplive, rtspAddr);
|
|
if (enCodecType == RK_CODEC_TYPE_H264) {
|
|
rtsp_set_video(g_rtsp_session[i], RTSP_CODEC_ID_VIDEO_H264, RK_NULL, 0);
|
|
} else if (enCodecType == RK_CODEC_TYPE_H265) {
|
|
rtsp_set_video(g_rtsp_session[i], RTSP_CODEC_ID_VIDEO_H265, RK_NULL, 0);
|
|
} else {
|
|
RK_LOGE("not support other type\n");
|
|
g_rtsp_ifenbale = RK_FALSE;
|
|
return RK_SUCCESS;
|
|
}
|
|
rtsp_sync_video_ts(g_rtsp_session[i], rtsp_get_reltime(), rtsp_get_ntptime());
|
|
RK_LOGE("rtsp <%s> init success", rtspAddr);
|
|
}
|
|
g_rtsp_ifenbale = RK_TRUE;
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 rtsp_deinit(void) {
|
|
if (g_rtsplive)
|
|
rtsp_del_demo(g_rtsplive);
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 global_param_init(void) {
|
|
|
|
gPThreadStatus = (ThreadStatus *)malloc(sizeof(ThreadStatus));
|
|
if (!gPThreadStatus) {
|
|
printf("malloc for gPThreadStatus failure\n");
|
|
goto __global_init_fail;
|
|
}
|
|
memset(gPThreadStatus, 0, sizeof(ThreadStatus));
|
|
|
|
if (RK_SUCCESS != pthread_mutex_init(&g_rtsp_mutex, RK_NULL)) {
|
|
RK_LOGE("pthread_mutex_init failure");
|
|
goto __global_init_fail;
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
|
|
__global_init_fail:
|
|
if (gPThreadStatus) {
|
|
free(gPThreadStatus);
|
|
gPThreadStatus = RK_NULL;
|
|
}
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
static RK_S32 global_param_deinit(void) {
|
|
|
|
if (gPThreadStatus) {
|
|
free(gPThreadStatus);
|
|
gPThreadStatus = RK_NULL;
|
|
}
|
|
|
|
pthread_mutex_destroy(&g_rtsp_mutex);
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* function : main()
|
|
* Description : main
|
|
******************************************************************************/
|
|
int main(int argc, char *argv[]) {
|
|
rk_aiq_mems_sensor_intf_t eis_api = {
|
|
.createContext = rkiio_aiq_sensor_ctx_create,
|
|
.destroyContext = rkiio_aiq_sensor_ctx_destroy,
|
|
.getSensorList = rkiio_aiq_sensors_list_get,
|
|
.releaseSensorList = rkiio_aiq_sensors_list_release,
|
|
.getSensorCapabilities = rkiio_aiq_sensor_cap_get,
|
|
.releaseSensorCapabilities = rkiio_aiq_sensor_cap_release,
|
|
.getConfig = rkiio_aiq_sensor_config_get,
|
|
.setConfig = rkiio_aiq_sensor_config_set,
|
|
.createHandle = rkiio_aiq_sensor_handle_create,
|
|
.destroyHandle = rkiio_aiq_sensor_handle_destroy,
|
|
.getData = rkiio_aiq_getData,
|
|
.getLastNSamples = rkiio_aiq_getLastNSamples,
|
|
.releaseSamplesData = rkiio_aiq_sensor_data_release,
|
|
};
|
|
SAMPLE_MPI_CTX_S *ctx = RK_NULL;
|
|
RK_S32 s32Ret = RK_FAILURE;
|
|
RK_U32 u32ViWidth = 1296;
|
|
RK_U32 u32ViHeight = 972;
|
|
RK_CHAR *pOutPath = NULL;
|
|
RK_CHAR *pDeviceName = NULL;
|
|
RK_S32 s32CamId = 0;
|
|
RK_S32 s32ChnId = 1;
|
|
RK_S32 s32loopCnt = -1;
|
|
RK_U32 u32VencFps = 25;
|
|
RK_U32 u32BitRate = 2 * 1024;
|
|
RK_U32 u32ViBuffCnt = 2;
|
|
RK_U32 u32VencBuffSize = 0;
|
|
RK_U32 EIS_Mode = 1;
|
|
CODEC_TYPE_E enCodecType = RK_CODEC_TYPE_H264;
|
|
VENC_RC_MODE_E enRcMode = VENC_RC_MODE_H264CBR;
|
|
MPP_CHN_S stSrcChn, stDestChn;
|
|
PIXEL_FORMAT_E PixelFormat = RK_FMT_YUV420SP;
|
|
COMPRESS_MODE_E CompressMode = COMPRESS_MODE_NONE;
|
|
rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
|
|
pthread_t venc_thread_id;
|
|
|
|
if (argc < 2) {
|
|
print_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
ctx = (SAMPLE_MPI_CTX_S *)(malloc(sizeof(SAMPLE_MPI_CTX_S)));
|
|
memset(ctx, 0, sizeof(SAMPLE_MPI_CTX_S));
|
|
|
|
s32Ret = global_param_init();
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("global_param_init failure");
|
|
g_exit_result = RK_FAILURE;
|
|
goto __PARAM_INIT_FAILED;
|
|
}
|
|
|
|
signal(SIGINT, sigterm_handler);
|
|
signal(SIGTERM, sigterm_handler);
|
|
|
|
#ifdef RKAIQ
|
|
RK_BOOL bMultictx = RK_FALSE;
|
|
#endif
|
|
int c;
|
|
char *iq_file_dir = NULL;
|
|
while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) {
|
|
const char *tmp_optarg = optarg;
|
|
switch (c) {
|
|
case 'a':
|
|
if (!optarg && NULL != argv[optind] && '-' != argv[optind][0]) {
|
|
tmp_optarg = argv[optind++];
|
|
}
|
|
if (tmp_optarg) {
|
|
iq_file_dir = (char *)tmp_optarg;
|
|
} else {
|
|
iq_file_dir = NULL;
|
|
}
|
|
break;
|
|
case 'd':
|
|
pDeviceName = optarg;
|
|
break;
|
|
case 'c':
|
|
s32ChnId = atoi(optarg);
|
|
break;
|
|
case 'f':
|
|
if (!strcmp(optarg, "nv12")) {
|
|
PixelFormat = RK_FMT_YUV420SP;
|
|
} else if (!strcmp(optarg, "nv16")) {
|
|
PixelFormat = RK_FMT_YUV422SP;
|
|
} else if (!strcmp(optarg, "uyvy")) {
|
|
PixelFormat = RK_FMT_YUV422_UYVY;
|
|
} else if (!strcmp(optarg, "yuyv")) {
|
|
PixelFormat = RK_FMT_YUV422_YUYV;
|
|
}
|
|
#if defined(RV1106)
|
|
else if (!strcmp(optarg, "rgb565")) {
|
|
PixelFormat = RK_FMT_RGB565;
|
|
s32ChnId = 1;
|
|
} else if (!strcmp(optarg, "xbgr8888")) {
|
|
PixelFormat = RK_FMT_XBGR8888;
|
|
s32ChnId = 1;
|
|
}
|
|
#endif
|
|
else {
|
|
RK_LOGE("this pixel_format is not supported in the sample");
|
|
print_usage(argv[0]);
|
|
goto __FAILED2;
|
|
}
|
|
break;
|
|
case 'w':
|
|
u32ViWidth = atoi(optarg);
|
|
break;
|
|
case 'h':
|
|
u32ViHeight = atoi(optarg);
|
|
break;
|
|
case 'e':
|
|
EIS_Mode = atoi(optarg);
|
|
break;
|
|
case 'I':
|
|
s32CamId = atoi(optarg);
|
|
break;
|
|
case 'l':
|
|
s32loopCnt = atoi(optarg);
|
|
break;
|
|
case 'o':
|
|
pOutPath = optarg;
|
|
break;
|
|
case 'h' + 'm':
|
|
if (atoi(optarg) == 0) {
|
|
hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
|
|
} else if (atoi(optarg) == 1) {
|
|
hdr_mode = RK_AIQ_WORKING_MODE_ISP_HDR2;
|
|
} else if (atoi(optarg) == 2) {
|
|
hdr_mode = RK_AIQ_WORKING_MODE_ISP_HDR3;
|
|
} else {
|
|
RK_LOGE("input hdr_mode is not support(error)");
|
|
print_usage(argv[0]);
|
|
goto __FAILED2;
|
|
}
|
|
break;
|
|
case '?':
|
|
default:
|
|
print_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
printf("#CameraIdx: %d\n", s32CamId);
|
|
printf("#pDeviceName: %s\n", pDeviceName);
|
|
printf("#Output Path: %s\n", pOutPath);
|
|
printf("#IQ Path: %s\n", iq_file_dir);
|
|
printf("#EIS_MODE: %d\n", EIS_Mode);
|
|
if (iq_file_dir) {
|
|
#ifdef RKAIQ
|
|
printf("#Rkaiq XML DirPath: %s\n", iq_file_dir);
|
|
printf("#bMultictx: %d\n\n", bMultictx);
|
|
|
|
SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, iq_file_dir);
|
|
if (EIS_Mode == 1) {
|
|
SAMPLE_COMM_ISP_RegMemsSensorIntf(s32CamId, &eis_api);
|
|
}
|
|
SAMPLE_COMM_ISP_Run(s32CamId);
|
|
#endif
|
|
}
|
|
|
|
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_SYS_Init failure");
|
|
g_exit_result = RK_FAILURE;
|
|
goto __FAILED;
|
|
}
|
|
|
|
s32Ret = rtsp_init(enCodecType);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("rtsp_init failure");
|
|
g_exit_result = RK_FAILURE;
|
|
goto __FAILED;
|
|
}
|
|
// Init VI
|
|
ctx->vi.u32Width = u32ViWidth;
|
|
ctx->vi.u32Height = u32ViHeight;
|
|
ctx->vi.s32DevId = s32CamId;
|
|
ctx->vi.u32PipeId = ctx->vi.s32DevId;
|
|
ctx->vi.s32ChnId = s32ChnId;
|
|
ctx->vi.stChnAttr.stIspOpt.stMaxSize.u32Width = u32ViWidth;
|
|
ctx->vi.stChnAttr.stIspOpt.stMaxSize.u32Height = u32ViHeight;
|
|
ctx->vi.stChnAttr.stIspOpt.u32BufCount = 2;
|
|
ctx->vi.stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
|
|
ctx->vi.stChnAttr.u32Depth = 1;
|
|
ctx->vi.stChnAttr.enPixelFormat = PixelFormat;
|
|
ctx->vi.stChnAttr.enCompressMode = CompressMode;
|
|
ctx->vi.stChnAttr.stFrameRate.s32SrcFrameRate = -1;
|
|
ctx->vi.stChnAttr.stFrameRate.s32DstFrameRate = -1;
|
|
ctx->vi.dstFilePath = pOutPath;
|
|
ctx->vi.s32loopCount = s32loopCnt;
|
|
ctx->vi.u32BufferLine = ctx->vi.u32Height;
|
|
if (pDeviceName) {
|
|
strcpy(ctx->vi.stChnAttr.stIspOpt.aEntityName, pDeviceName);
|
|
}
|
|
s32Ret = SAMPLE_COMM_VI_CreateChn(&ctx->vi);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
g_exit_result = RK_FAILURE;
|
|
RK_LOGE("SAMPLE_COMM_VI_CreateChn failure:%d", s32Ret);
|
|
goto __FAILED;
|
|
}
|
|
|
|
/* Init VENC*/
|
|
ctx->venc.s32ChnId = 0;
|
|
ctx->venc.u32Width = u32ViWidth;
|
|
ctx->venc.u32Height = u32ViHeight;
|
|
ctx->venc.u32Fps = u32VencFps;
|
|
ctx->venc.u32Gop = 50;
|
|
ctx->venc.u32BitRate = u32BitRate;
|
|
ctx->venc.enCodecType = enCodecType;
|
|
ctx->venc.enRcMode = enRcMode;
|
|
ctx->venc.getStreamCbFunc = venc_get_stream;
|
|
ctx->venc.s32loopCount = s32loopCnt;
|
|
ctx->venc.dstFilePath = pOutPath;
|
|
ctx->venc.u32BufferLine = ctx->venc.u32Height;
|
|
if (u32VencBuffSize) {
|
|
ctx->venc.u32BuffSize = u32VencBuffSize;
|
|
} else {
|
|
ctx->venc.u32BuffSize = u32ViWidth * u32ViHeight / 2;
|
|
}
|
|
if (RK_CODEC_TYPE_H264 != enCodecType) {
|
|
ctx->venc.stChnAttr.stVencAttr.u32Profile = 0;
|
|
} else {
|
|
ctx->venc.stChnAttr.stVencAttr.u32Profile = 100;
|
|
}
|
|
s32Ret = SAMPLE_COMM_VENC_CreateChn(&ctx->venc);
|
|
if (s32Ret == RK_SUCCESS) {
|
|
RK_LOGE("SAMPLE_COMM_VENC_CreateChn success:%d", s32Ret);
|
|
}
|
|
|
|
/* VI bind VENC */
|
|
stSrcChn.enModId = RK_ID_VI;
|
|
stSrcChn.s32DevId = ctx->vi.s32DevId;
|
|
stSrcChn.s32ChnId = ctx->vi.s32ChnId;
|
|
stDestChn.enModId = RK_ID_VENC;
|
|
stDestChn.s32DevId = 0;
|
|
stDestChn.s32ChnId = ctx->venc.s32ChnId;
|
|
s32Ret = SAMPLE_COMM_Bind(&stSrcChn, &stDestChn);
|
|
if (s32Ret == RK_SUCCESS) {
|
|
RK_LOGE("VI and VENC bind success:%X", s32Ret);
|
|
} else {
|
|
program_handle_error(__func__, __LINE__);
|
|
}
|
|
|
|
pthread_create(&venc_thread_id, 0, venc_get_stream, (void *)&ctx->venc);
|
|
|
|
printf("%s initial finish\n", __func__);
|
|
|
|
while (!gPThreadStatus->bIfMainThreadQuit) {
|
|
sleep(1);
|
|
}
|
|
|
|
printf("%s exit!\n", __func__);
|
|
|
|
pthread_join(ctx->venc.getStreamThread, RK_NULL);
|
|
|
|
/* VI unbind VENC and destroy venc*/
|
|
stSrcChn.enModId = RK_ID_VI;
|
|
stSrcChn.s32DevId = ctx->vi.s32DevId;
|
|
stSrcChn.s32ChnId = ctx->vi.s32ChnId;
|
|
stDestChn.enModId = RK_ID_VENC;
|
|
stDestChn.s32DevId = 0;
|
|
stDestChn.s32ChnId = ctx->venc.s32ChnId;
|
|
s32Ret = SAMPLE_COMM_UnBind(&stSrcChn, &stDestChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("VI and VENC bind failure:%X", s32Ret);
|
|
g_exit_result = RK_FAILURE;
|
|
}
|
|
SAMPLE_COMM_VENC_DestroyChn(&ctx->venc);
|
|
s32Ret = SAMPLE_COMM_VI_DestroyChn(&ctx->vi);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_DisableChn failure:%X", s32Ret);
|
|
g_exit_result = RK_FAILURE;
|
|
}
|
|
rtsp_deinit();
|
|
|
|
__FAILED:
|
|
RK_MPI_SYS_Exit();
|
|
if (iq_file_dir) {
|
|
#ifdef RKAIQ
|
|
SAMPLE_COMM_ISP_Stop(s32CamId);
|
|
#endif
|
|
}
|
|
__FAILED2:
|
|
global_param_deinit();
|
|
|
|
if (ctx) {
|
|
free(ctx);
|
|
ctx = RK_NULL;
|
|
}
|
|
__PARAM_INIT_FAILED:
|
|
return g_exit_result;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
#endif
|
|
#endif /* End of #ifdef __cplusplus */
|