Files

852 lines
27 KiB
C

/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "sample_comm.h"
#include "sample_comm_venc.h"
#include "sample_comm_vpss.h"
#include "sample_comm_vi.h"
#include "sample_comm_sys.h"
#include "sample_comm_isp.h"
#include "video_stream.h"
#include "sample_video.h"
#include "sample_video_dual.h"
#include "venc_log.h"
#include "frame_cache.h"
static int g_start = 0;
static pthread_t g_recv_pid;
static sample_venc_getstream_para g_st_param;
//common
struct dual_comm {
sample_comm_sensor_type sensor_type;
sample_comm_video_param video_param;
};
// vi config
struct dual_vi {
xmedia_s32 vi_dev; /* 0:单板SENSOR0; 2:单板SENSOR2 */
xmedia_s32 vi_chn;
xmedia_s32 vi_pipe;
sample_vi_config vi_cfg;
};
// isp config
struct dual_isp {
sample_isp_param isp_param;
};
// vpss config
struct dual_vpss {
xmedia_s32 vpss_pipe;
xmedia_s32 vpss_ichn;
xmedia_s32 vpss_ochn;
sample_vpss_config vpss_cfg;
};
// venc config
struct dual_venc {
xmedia_s32 venc_chn;
sample_venc_config venc_cfg;
};
struct dual_stream {
xmedia_s32 stream_id;
struct dual_comm comm;
struct dual_vi vi;
struct dual_isp isp;
struct dual_vpss vpss;
struct dual_venc venc;
};
#define STREAM_NUMS 4
static struct dual_stream g_stream[STREAM_NUMS];
static void sample_dual_config_comm(struct dual_comm* comm, sample_comm_sensor_type sns_type)
{
comm->sensor_type = sns_type;
comm->video_param.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
comm->video_param.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420;
comm->video_param.data_width = XMEDIA_VIDEO_DATA_WIDTH_8;
comm->video_param.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
}
static void sample_dual_config_vi(struct dual_vi* vi,
xmedia_s32 vi_chn,
xmedia_s32 vi_dev,
xmedia_s32 vi_pipe,
sample_comm_sensor_type sns_type)
{
vi->vi_chn = vi_chn;
vi->vi_dev = vi_dev;
vi->vi_pipe = vi_pipe;
vi->vi_cfg.dev_info[vi_dev].dev_no = vi_dev;
vi->vi_cfg.dev_info[vi_dev].dev_en = XMEDIA_TRUE;
vi->vi_cfg.dev_info[vi_dev].sensor_type = sns_type;
vi->vi_cfg.pipe_info[vi_pipe].pipe_no = vi_pipe;
vi->vi_cfg.pipe_info[vi_pipe].pipe_en = XMEDIA_TRUE;
vi->vi_cfg.pipe_info[vi_pipe].chn_info[vi_chn].chn_no = vi_chn;
vi->vi_cfg.pipe_info[vi_pipe].chn_info[vi_chn].chn_en = XMEDIA_TRUE;
vi->vi_cfg.dev_bind_pipe[vi_dev].pipe[0] = vi_pipe;
vi->vi_cfg.dev_bind_pipe[vi_dev].pipe[1] = -1;
}
static void sample_dual_config_isp(struct dual_isp* isp,
xmedia_s32 vi_pipe,
sample_comm_sensor_type sns_type)
{
xmedia_u32 framerate = 0;
vi_sensor_info sensor_info = {0};
sample_comm_vi_get_sensor_info(sns_type, &sensor_info);
sample_comm_vi_get_framerate_by_sensor(sns_type, &framerate);
// isp config init
isp->isp_param.isp_info[vi_pipe].isp_config.fps = framerate;
isp->isp_param.isp_info[vi_pipe].isp_config.mode_config.work_mode = XMEDIA_ISP_WORK_MODE_MASTER;
isp->isp_param.isp_info[vi_pipe].isp_config.mode_config.master_mode.blend_stat_enable = XMEDIA_FALSE;
isp->isp_param.isp_info[vi_pipe].isp_config.mode_config.master_mode.slave_num = 0;
isp->isp_param.isp_info[vi_pipe].isp_config.pixel_fmt = sensor_info.pixel_format;
isp->isp_param.isp_info[vi_pipe].isp_config.size.height = sensor_info.height;
isp->isp_param.isp_info[vi_pipe].isp_config.size.width = sensor_info.width;
isp->isp_param.isp_info[vi_pipe].isp_config.wdr_mode = sensor_info.wdr_mode;
// isp pipe init
isp->isp_param.pipe[vi_pipe] = vi_pipe;
isp->isp_param.isp_info[vi_pipe].flip = XMEDIA_FALSE;
isp->isp_param.isp_info[vi_pipe].mirror = XMEDIA_FALSE;
isp->isp_param.isp_info[vi_pipe].isp_pipe_en = XMEDIA_TRUE;
isp->isp_param.isp_info[vi_pipe].isp_sensor_en = XMEDIA_TRUE;
isp->isp_param.isp_info[vi_pipe].sensor_type = sns_type;
}
static void sample_dual_config_vpss(struct dual_vpss* vpss,
xmedia_s32 vpss_pipe,
xmedia_s32 vpss_ichn,
xmedia_s32 vpss_ochn)
{
vpss->vpss_pipe = vpss_pipe;
vpss->vpss_ichn = vpss_ichn;
vpss->vpss_ochn = vpss_ochn;
//vpss->vpss_cfg = ;
}
static void sample_dual_config_venc(struct dual_venc* venc,
xmedia_s32 venc_chnl)
{
venc->venc_chn = venc_chnl;
venc->venc_cfg.chn_info[venc_chnl].venc_en = XMEDIA_TRUE;
venc->venc_cfg.chn_info[venc_chnl].venc_chn = venc_chnl;
venc->venc_cfg.chn_info[venc_chnl].payload_type = PT_H264;
venc->venc_cfg.chn_info[venc_chnl].rc_mode = VENC_RC_MODE_H264CBR;
}
static void sammple_dual_stream_config(void)
{
xmedia_s32 id;
xmedia_s32 vi_dev[STREAM_NUMS] = {0, 0, 2, 2};
xmedia_s32 vi_pipe[STREAM_NUMS] = {0, 0, 1, 1};
xmedia_s32 vi_chn[STREAM_NUMS] = {0, 0, 0, 0};
xmedia_s32 vpss_pipe[STREAM_NUMS] = {0, 0, 1, 1};
xmedia_s32 vpss_ichn[STREAM_NUMS] = {0, 0, 0, 0};
xmedia_s32 vpss_ochn[STREAM_NUMS] = {0, 1, 0, 1};
xmedia_s32 venc_chnl[STREAM_NUMS] = {0, 1, 2, 3};
sample_comm_sensor_type sns_type[STREAM_NUMS] = {SENSOR0_TYPE, SENSOR0_TYPE, SENSOR1_TYPE, SENSOR1_TYPE};
for (id = 0; id < STREAM_NUMS; id++) {
g_stream[id].stream_id = id;
sample_dual_config_comm(&g_stream[id].comm, sns_type[id]);
sample_dual_config_vi(&g_stream[id].vi, vi_chn[id], vi_dev[id], vi_pipe[id], sns_type[id]);
sample_dual_config_isp(&g_stream[id].isp, vi_pipe[id], sns_type[id]);
sample_dual_config_vpss(&g_stream[id].vpss, vpss_pipe[id], vpss_ichn[id], vpss_ochn[id]);
sample_dual_config_venc(&g_stream[id].venc, venc_chnl[id]);
}
}
static int sample_dual_sys_init(void)
{
xmedia_s32 ret;
xmedia_s32 id;
xmedia_s32 blk_size, pool_id;
xmedia_s32 vi_pipe;
sample_comm_sensor_type sensor_type;
vi_sensor_info sensor_info = {0};
xmedia_video_size pic_size = {0};
sample_sys_config sys_config = {0};
sample_comm_video_param* video_param = NULL;
func_entry();
sammple_dual_stream_config();
pool_id = 0;
for (id = 0; id < STREAM_NUMS; id++) {
sensor_type = g_stream[id].comm.sensor_type;
sample_comm_vi_get_sensor_info(sensor_type, &sensor_info);
// sys init
vi_pipe = g_stream[id].vi.vi_pipe;
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;
pic_size.width = sensor_info.width;
pic_size.height = sensor_info.height;
venc_logd("resolution: w(%d) x h(%d).\n", pic_size.width, pic_size.height);
video_param = &g_stream[id].comm.video_param;
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[pool_id].block_size = blk_size;
sys_config.vb_conf.common_pool[pool_id].block_cnt = 5;
venc_logd("allocate cache pool %d: size(%d) x cnt(%d)\n", pool_id, blk_size, 5);
pool_id++;
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[pool_id].block_size = blk_size;
sys_config.vb_conf.common_pool[pool_id].block_cnt = 5;
venc_logd("allocate cache pool %d: size(%d) x cnt(%d)\n", pool_id, blk_size, 5);
pool_id++;
}
sys_config.vb_conf.supplement_config = (1 << 0);
sys_config.vb_conf.supplement_config |= (1 << 1);
ret = sample_comm_sys_init(&sys_config);
if(ret != XMEDIA_SUCCESS) {
venc_loge("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) {
venc_loge("sample_comm_vi_init failed!\n");
return ret;
}
ret = sample_comm_vpss_init();
if(ret != XMEDIA_SUCCESS) {
venc_loge("sample_comm_vpss_init failed!\n");
return ret;
}
ret = sample_comm_venc_init();
if(ret != XMEDIA_SUCCESS) {
venc_loge("sample_comm_venc_init failed!\n");
return ret;
}
func_success();
return XMEDIA_SUCCESS;
}
static int sample_dual_sys_deinit(void)
{
sample_comm_venc_exit();
sample_comm_vpss_exit();
sample_comm_vi_exit();
sample_comm_sys_exit();
return XMEDIA_SUCCESS;
}
static FILE* fp[4] = {NULL, NULL, NULL, NULL};
char filename[4][32] = {
{"stream_dev.h264"},
{"stream_1.h264"},
{"stream_2.h264"},
{"stream_3.h264"}
};
struct dual_head {
unsigned int id;
unsigned int stream_offset;
unsigned int stream_size;
unsigned char reserve[4];
};
void save_stream(char* stream, int length)
{
int w_actl = 0;
int recv_size = length;
unsigned int offset, size;
unsigned int id = 0;
unsigned char* tmp = (unsigned char*)stream;
struct dual_head* stream_head = NULL;
while (recv_size > 0) {
stream_head = (struct dual_head*)stream;
id = stream_head->id;
offset = stream_head->stream_offset;
size = stream_head->stream_size;
if (id >= STREAM_NUMS) {
printf("Error: Invalid stream id.\n");
return ;
}
//printf("id(%u), off(%u), size(%u)\n", id, offset, size);
tmp += offset;
if (fp[id] != NULL) {
w_actl = fwrite(tmp, 1, size, fp[id]);
}
if (w_actl != size) {
//printf("Warning: exp(%d) != acl(%d).", size, w_actl);
}
tmp += size;
recv_size -= (offset + size);
}
}
static int sample_dual_save_data(xmedia_venc_stream* pst_stream, int id)
{
int i = 0;
xmedia_venc_pack *pst_data = NULL;
unsigned char *s = NULL;
unsigned int data_len = 0;
unsigned int copy_size = 0;
struct dual_head head = {0};
uvc_cache_t *uvc_cache = uvc_cache_get();
frame_node_t *fnode = NULL;
if (uvc_cache) {
get_node_from_queue(uvc_cache->free_queue, &fnode);
}
if (!fnode) {
venc_logd("drop frame.\n");
return XMEDIA_SUCCESS;
}
fnode->used = sizeof(struct dual_head);
head.id = id;
head.stream_offset = sizeof(struct dual_head);
head.stream_size = 0;
for (i = 0; i < pst_stream->pack_count; ++i) {
pst_data = &pst_stream->pack[i];
s = pst_data->vir_addr + pst_data->offset;
data_len = pst_data->len - pst_data->offset;
copy_size = data_len < (fnode->length - fnode->used) ? data_len : (fnode->length - fnode->used);
if (copy_size > 0) {
memcpy(fnode->mem + fnode->used, s, copy_size);
fnode->used += copy_size;
head.stream_size += copy_size;
}
if (data_len > copy_size) {
venc_logw("fnode->length = %u\n", fnode->length);
venc_logw("WARN: missing pack. exp(%u) != act(%u)\n", data_len, copy_size);
}
}
memcpy(fnode->mem, (void*)&head, sizeof(struct dual_head));
//fwrite((char*)(fnode->mem), 1, 16, fp[0]);
if (fp[id] != NULL) {
//fwrite((char*)(fnode->mem + head.stream_offset), 1, head.stream_size, fp[id]);
//save_stream((char*)fnode->mem, fnode->used);
}
venc_logd("send size(%u)\n", fnode->used);
put_node_to_queue(uvc_cache->ok_queue, fnode);
return XMEDIA_SUCCESS;
}
static int sample_dual_save_stream(xmedia_payload_type en_type, xmedia_venc_stream *pst_stream, int id)
{
xmedia_s32 ret = XMEDIA_FAILURE;
if (PT_H264 == en_type) {
ret = sample_dual_save_data(pst_stream, id);
}
return ret;
}
static void* sample_dual_stream_proc(void* arg)
{
xmedia_s32 i;
xmedia_s32 ret = XMEDIA_FAILURE;
xmedia_venc_chn_attr venc_chn_attr;
xmedia_payload_type payload_type[VENC_MAX_CHN_NUM];
sample_venc_getstream_para *param = (sample_venc_getstream_para*)arg;
xmedia_s32 chn_cnt = param->cnt;
struct timeval time_out;
xmedia_venc_stream venc_stream;
xmedia_venc_chn_status stat;
xmedia_u32 venc_mask = 0;
if (chn_cnt >= VENC_MAX_CHN_NUM) {
venc_loge("input venc chn count invaild\n");
return XMEDIA_NULL;
}
for (i = 0; i < chn_cnt; ++i) {
if (param->venc_chn[i] < 0) {
continue;
}
ret = xmedia_venc_get_chn_attr(param->venc_chn[i], &venc_chn_attr);
if (XMEDIA_SUCCESS != ret) {
venc_loge("xmedia_venc_get_chn_attr chn[%d] failed with %#x!\n", param->venc_chn[i], ret);
return XMEDIA_NULL;
}
payload_type[i] = venc_chn_attr.venc_attr.en_type;
venc_mask |= 1 << param->venc_chn[i];
if (fp[i] == NULL) {
fp[i] = fopen((char*)filename[i], "w+");
}
}
venc_logi("Dual start.\n");
while (param->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) {
venc_loge("select err\n");
break;
} else if (ret == XMEDIA_ERRCODE_TIMEOUT) {
param->stream_timeout_cnt++;
venc_logd("get venc stream time out, continue. \n");
continue;
}
for (i = 0; i < chn_cnt; ++i) {
if (param->venc_chn[i] < 0) {
continue;
}
ret = xmedia_venc_query_status(param->venc_chn[i], &stat);
if (XMEDIA_SUCCESS != ret) {
venc_logd("xmedia_venc_query_status chn[%d] failed with %#x!\n", i, ret);
break;
}
if (0 == stat.cur_packs) {
continue;
}
memset(&venc_stream, 0, sizeof(venc_stream));
venc_stream.pack = (xmedia_venc_pack*)malloc(sizeof(xmedia_venc_pack) * stat.cur_packs);
if (XMEDIA_NULL == venc_stream.pack) {
venc_logd("malloc stream pack failed!\n");
break;
}
venc_stream.pack_count = stat.cur_packs;
ret = xmedia_venc_get_stream(param->venc_chn[i], &venc_stream, XMEDIA_TRUE);
if (XMEDIA_SUCCESS != ret) {
free(venc_stream.pack);
venc_stream.pack = XMEDIA_NULL;
xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
venc_loge("xmedia_venc_get_stream failed with %#x!\n", ret);
break;
}
sample_dual_save_stream(payload_type[i], &venc_stream, i);
ret = xmedia_venc_release_stream(param->venc_chn[i], &venc_stream);
if (XMEDIA_SUCCESS != ret) {
venc_loge("xmedia_venc_release_stream failed!\n");
free(venc_stream.pack);
venc_stream.pack = XMEDIA_NULL;
break;
}
free(venc_stream.pack);
venc_stream.pack = XMEDIA_NULL;
}
}
for (i = 0; i < 4; i++) {
if (fp[i] != NULL) {
fclose(fp[i]);
}
fp[i] = NULL;
}
venc_logi("Dual stream exit.\n");
return NULL;
}
static int sample_dual_start_get_stream()
{
int i, rc;
g_st_param.cnt = STREAM_NUMS;
g_st_param.thread_start = XMEDIA_TRUE;
for (i = 0; i < STREAM_NUMS; i++) {
g_st_param.venc_chn[i] = g_stream[i].venc.venc_chn;
}
rc = pthread_create(&g_recv_pid, NULL, sample_dual_stream_proc, (void*)&g_st_param);
if (rc < 0) {
venc_loge("Create sample_dual_stream_proc failed.\n");
return -1;
}
return 0;
}
static int sample_dual_stop_get_stream(void)
{
if (XMEDIA_TRUE == g_st_param.thread_start) {
g_st_param.thread_start = XMEDIA_FALSE;
pthread_join(g_recv_pid, 0);
}
venc_logi("stop get Dual stream ok.\n");
return 0;
}
static int sample_dual_normalp_classic(void)
{
xmedia_s32 id;
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 framerate = 0;
xmedia_video_size pic_size = {0};
xmedia_video_size vpss_ochn_size = {0};
//xmedia_isp_config isp_config = {0};
xmedia_payload_type en_payload = PT_H264;
vi_sensor_info sensor_info = {0};
xmedia_s32 venc_chn_0, venc_chn_1;
xmedia_s32 vi_pipe, vi_chn;
xmedia_s32 vpss_pipe, vpss_ichn, vpss_ochn_0, vpss_ochn_1;
sample_comm_sensor_type sensor_type;
sample_isp_param* isp_param = NULL;
sample_vi_config* vi_config = NULL;
sample_vpss_config* vpss_config = NULL;
sample_venc_config* venc_config = NULL;
sample_comm_video_param* video_param = NULL;
for (id = 0; id < STREAM_NUMS; id++) {
#if 0
g_vi_config.dev_info[g_vi_dev].dev_en = XMEDIA_TRUE;
g_vi_config.dev_info[g_vi_dev].dev_no = g_vi_dev;
g_vi_config.dev_info[g_vi_dev].sensor_type = g_sensor_type;
g_vi_config.pipe_info[g_vi_pipe].pipe_en = XMEDIA_TRUE;
g_vi_config.pipe_info[g_vi_pipe].pipe_no = g_vi_pipe;
g_vi_config.pipe_info[g_vi_pipe].chn_info[g_vi_chn].chn_en = XMEDIA_TRUE;
g_vi_config.pipe_info[g_vi_pipe].chn_info[g_vi_chn].chn_no = g_vi_chn;
g_vi_config.dev_bind_pipe[g_vi_dev].pipe[0] = g_vi_pipe;
g_vi_config.dev_bind_pipe[g_vi_dev].pipe[1] = -1;
#endif
sensor_type = g_stream[id].comm.sensor_type;
sample_comm_vi_get_sensor_info(sensor_type, &sensor_info);
sample_comm_vi_get_framerate_by_sensor(sensor_type, &framerate);
pic_size.height = sensor_info.height;
pic_size.width = sensor_info.width;
#if 0
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
g_isp_param.pipe[g_vi_pipe] = g_vi_pipe;
g_isp_param.isp_info[g_vi_pipe].sensor_type = g_sensor_type;
g_isp_param.isp_info[g_vi_pipe].flip = XMEDIA_FALSE;
g_isp_param.isp_info[g_vi_pipe].mirror = XMEDIA_FALSE;
g_isp_param.isp_info[g_vi_pipe].isp_pipe_en = XMEDIA_TRUE;
g_isp_param.isp_info[g_vi_pipe].isp_sensor_en = XMEDIA_TRUE;
memcpy(&(g_isp_param.isp_info[g_vi_pipe].isp_config), &isp_config, sizeof(xmedia_isp_config));
#endif
// isp init
isp_param = &g_stream[id].isp.isp_param;
vi_config = &g_stream[id].vi.vi_cfg;
ret = sample_comm_isp_init(isp_param, vi_config);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] isp init failed!\n", id);
}
// vi start
vi_config = &g_stream[id].vi.vi_cfg;
video_param = &g_stream[id].comm.video_param;
ret = sample_comm_vi_start(vi_config, video_param);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] start vi failed!\n", id);
}
// isp start
isp_param = &g_stream[id].isp.isp_param;
ret = sample_comm_isp_start(isp_param);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] start isp failed!\n", id);
}
// vpss config
vpss_pipe = g_stream[id].vpss.vpss_pipe;
vpss_ichn = g_stream[id].vpss.vpss_ichn;
vpss_ochn_0 = g_stream[id].vpss.vpss_ochn;
vpss_ochn_1 = g_stream[id + 1].vpss.vpss_ochn;
vpss_config = &g_stream[id].vpss.vpss_cfg;
video_param = &g_stream[id].comm.video_param;
ret = sample_comm_vpss_get_default_pipe_cfg(&vpss_config->pipe_info[vpss_pipe].pipe_config,
pic_size,
video_param);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] get default pipe cfg failed !\n", id);
}
get_user_format(&en_payload, &pic_size, NULL);
vpss_ochn_size.width = pic_size.width;
vpss_ochn_size.height = pic_size.height;
vpss_config->pipe_info[vpss_pipe].pipe_en = XMEDIA_TRUE;
vpss_config->pipe_info[vpss_pipe].pipe_no = vpss_pipe;
#if 0
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn].chn_no = vpss_ochn;
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn].chn_en = XMEDIA_TRUE;
#else
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_0].chn_no = vpss_ochn_0;
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_0].chn_en = XMEDIA_TRUE;
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_1].chn_no = vpss_ochn_1;
vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_1].chn_en = XMEDIA_TRUE;
#endif
#if 0
ret = sample_comm_vpss_get_default_ochn_cfg(
&vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn].chn_config,
vpss_ochn_size,
video_param);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] get default pipe cfg failed !\n", id);
}
#else
ret = sample_comm_vpss_get_default_ochn_cfg(
&vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_0].chn_config,
vpss_ochn_size,
video_param);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] get default pipe cfg failed !\n", id);
}
ret = sample_comm_vpss_get_default_ochn_cfg(
&vpss_config->pipe_info[vpss_pipe].chn_info[vpss_ochn_1].chn_config,
vpss_ochn_size,
video_param);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] get default pipe cfg failed !\n", id + 1);
}
#endif
// vpss start
ret = sample_comm_vpss_start(vpss_config);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] vpss start failed !\n", id);
}
vi_chn = g_stream[id].vi.vi_chn;
vi_pipe = g_stream[id].vi.vi_pipe;
vpss_ichn = g_stream[id].vpss.vpss_ichn;
vpss_pipe = g_stream[id].vpss.vpss_pipe;
ret = sample_comm_sys_vi_bind_vpss(vi_pipe, vi_chn, vpss_pipe, vpss_ichn);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] vi bind vpss failed !\n", id);
}
//venc init
venc_chn_0 = g_stream[id].venc.venc_chn;
venc_config = &g_stream[id].venc.venc_cfg;
venc_config->chn_info[venc_chn_0].venc_chn = venc_chn_0;
venc_config->chn_info[venc_chn_0].venc_en = XMEDIA_TRUE;
venc_config->chn_info[venc_chn_0].payload_type = en_payload;
venc_config->chn_info[venc_chn_0].rc_mode = VENC_RC_MODE_H264CBR;
sample_comm_venc_get_default_chn_info(vpss_ochn_size,
framerate,
&venc_config->chn_info[venc_chn_0]);
ret = sample_comm_venc_start(venc_config);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] venc start failed !\n", id);
}
venc_chn_1 = g_stream[id + 1].venc.venc_chn;
venc_config = &g_stream[id + 1].venc.venc_cfg;
venc_config->chn_info[venc_chn_1].venc_chn = venc_chn_1;
venc_config->chn_info[venc_chn_1].venc_en = XMEDIA_TRUE;
venc_config->chn_info[venc_chn_1].payload_type = en_payload;
venc_config->chn_info[venc_chn_1].rc_mode = VENC_RC_MODE_H264CBR;
sample_comm_venc_get_default_chn_info(vpss_ochn_size,
framerate,
&venc_config->chn_info[venc_chn_1]);
ret = sample_comm_venc_start(venc_config);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] venc start failed !\n", id);
}
ret = sample_comm_sys_vpss_bind_venc(vpss_pipe, vpss_ochn_0, venc_chn_0);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] vpss bind venc failed !\n", id);
}
ret = sample_comm_sys_vpss_bind_venc(vpss_pipe, vpss_ochn_1, venc_chn_1);
if (ret != XMEDIA_SUCCESS) {
venc_loge("stream[%d] vpss bind venc failed !\n", id);
}
id++;
}
return 0;
}
/*******************************************************
* Processing Unit Operation Functions
*******************************************************/
/* Processing Unit Operation Functions End */
/*******************************************************
* Input Terminal Operation Functions
*******************************************************/
/* Input Terminal Operation Functions End */
/*******************************************************
* Stream Control Operation Functions
*******************************************************/
int sample_dual_set_idr(void)
{
return 0;
}
int sample_dual_init(void)
{
sample_dual_sys_init();
return 0;
}
int sample_dual_startup(void)
{
venc_logi("Dual stream startup.\n");
g_start = 1;
if (sample_dual_normalp_classic() < 0) {
return -1;
}
sample_dual_start_get_stream();
venc_logi("Dual stream startup ok.\n");
return 0;
}
int sample_dual_shutdown(void)
{
xmedia_s32 id;
xmedia_s32 vi_pipe, vi_chn;
xmedia_s32 vpss_pipe, vpss_ichn, vpss_ochn_0, vpss_ochn_1;
xmedia_s32 venc_chn_0, venc_chn_1;
sample_venc_config* venc_config = NULL;
sample_vpss_config* vpss_config = NULL;
sample_isp_param* isp_param = NULL;
sample_vi_config* vi_config = NULL;
if (!g_start) {
return 0;
}
sample_dual_stop_get_stream();
for (id = 0; id < STREAM_NUMS; id++) {
venc_config = &g_stream[id].venc.venc_cfg;
sample_comm_venc_stop(venc_config);
venc_config = &g_stream[id + 1].venc.venc_cfg;
sample_comm_venc_stop(venc_config);
vpss_pipe = g_stream[id].vpss.vpss_pipe;
vpss_ichn = g_stream[id].vpss.vpss_ichn;
vpss_ochn_0 = g_stream[id].vpss.vpss_ochn;
vpss_ochn_1 = g_stream[id + 1].vpss.vpss_ochn;
venc_chn_0 = g_stream[id].venc.venc_chn;
venc_chn_1 = g_stream[id + 1].venc.venc_chn;
sample_comm_sys_vpss_unbind_venc(vpss_pipe, vpss_ochn_0, venc_chn_0);
sample_comm_sys_vpss_unbind_venc(vpss_pipe, vpss_ochn_1, venc_chn_1);
vi_pipe = g_stream[id].vi.vi_pipe;
vi_chn = g_stream[id].vi.vi_chn;
sample_comm_sys_vi_unbind_vpss(vi_pipe, vi_chn, vpss_pipe, vpss_ichn);
vpss_config = &g_stream[id].vpss.vpss_cfg;
sample_comm_vpss_stop(vpss_config);
isp_param = &g_stream[id].isp.isp_param;
sample_comm_isp_stop(isp_param);
vi_config = &g_stream[id].vi.vi_cfg;
sample_comm_vi_stop(vi_config);
sample_comm_isp_exit(isp_param);
id++;
}
sample_dual_sys_deinit();
g_start = 0;
return 0;
}