Iot SDK 4.0.0
载入中...
搜索中...
未找到
Unisoc_W217 平台集成说明

本文是 Juphoon RTOS RTC SDK 包的一部分。主要目标是帮助集成人员
了解基本流程,可以快速的集成并验证音视频功能。

  1. release_note.txt 版本的发布说明和历史记录
  2. C 语言头文件:
    • jrtc.h 应用层接口头文件,函数原型和详细的注释说明
    • jrtc0.h 较低层高级接口,可定制化的部分参数和对应的注释说明
  3. C 静态库 libjrtc.a 所在目录:
    • libs/UWS6121E_WC_1H00 UWS6121E 的正式版库
  4. readme.md 该 SDK 说明文档

因为音视频功能依赖硬件支持, 所以 **不提供模拟器版本的库**。

一对一语音呼叫 Juphoon Cloud 终端

  1. 配置全局环境
    /* 配置参数:
    - AppKey 是应用在菊风云平台中的唯一标识,类似应用的身份证.
    必须通过在平台创建应用获取, 请参考如下文档:
    https://developer.juphoon.com/cn/juphoon_platform/03_console_description/03_app_management.html
    - UID 是设备在菊风云平台的账号,类似设备的身份证.
    自定义后, 必须在平台导入该账号, 请参考如下文档:
    https://developer.juphoon.com/cn/cat_1/01_import_iot_account.html
    - Key 是设备在通讯时的对称秘钥, 用于增强安全.
    必须在从平台获取或导入, 请参考如下文档:
    https://developer.juphoon.com/cn/cat_1/00_get_secret_key.html
    */
    jrtc_config (AppKey, UID, Key, "");
    void jrtc_config(const char appKey[24], const char license[64], const char aesKey[16], const char tokens[128], const struct jrtc_handler_t *handler)
    全局配置, 只需调用一次, 内部将复制所有参数
  2. 呼叫 Juphoon Cloud 终端
    /* 打开通话 */
    struct jrtc_t* jc = jrtc_open (对方账号, "", NULL, NULL);
    /* 开启音频发送 */
    void jrtc_activate(struct jrtc_t *jc, int devices)
    开启发送状态.
    struct jrtc_t * jrtc_open(const char channelId[64], const char uid[64], struct jrtc_image_t *video, struct jrtc_image_t *camera, struct jrtc_options_t *options)
    分配通话资源并启动网络线程.
    @ JRTC_AUDIO
    定义 jrtc.h:589

一对一视频呼叫 Juphoon Cloud 终端

  1. 呼叫 Juphoon Cloud 终端
    /* 配置环境, 请参考上面的'一对一语音呼叫' */
    jrtc_config (AppKey, UID, Key, "");
    /* width 和 height 设置值随硬件而异,一般要求必须是8的倍数;镜头采集的固定输出为240*240.
    - 图像需旋转90度, 所以height x width 也不能大于屏幕尺寸.
    - 内部 JPG 编码, 所以kbps不启作用, 只须 > 0
    - fps 可以控制最大帧速
    */
    static struct jrtc_image_t _video, _camera;
    _video.width = _camera.width = 176;
    _video.height = _camera.height = 176;
    _video.fps = _camera.fps = 10;
    _video.kbps = _camera.kbps = 120;
    struct jrtc_t* jc = jrtc_open (对方账号, "", &_video, &_camera);
    jrtc_activate(jc, JRTC_AUDIO|JRTC_CAMERA); /*< 开启音频和镜头的发送 */
    @ JRTC_CAMERA
    定义 jrtc.h:588
    视频流中的图像
    定义 jrtc.h:179
    unsigned short width
    图像宽
    定义 jrtc.h:182
  2. 创建定时器并激活
    SCI_TIMER_PTR* timer = SCI_CreatePeriodTimer("render", OnTimer, (uint32)0, 40, 0);
    SCI_ActiveTimer(timer);
  3. 在定时回调函数中,绘制视频图像
    static void OnTimer(uint32 p) {
    struct jrtc_image_t* img = &_video;
    if (img->get != img->put) {
    lcd_show(img); /*< 显示图像*/
    img->get = img->put; /*< 复位读计数 */
    }
    }
    static void lcd_show(struct jrtc_image_t*image) {
    uint8 *yuv_addr = image->data;
    unsigned short width = image->width, height = image->height;
    LCD_INFO_T lcd_info;
    uint16 *dest_ptr;
    uint32 i;
    BLOCKCFG_T cfg;
    //uint32 frame_size = width * height * 3 / 2;//yuv420p
    uint32 frame_size = width * height * 2;//UYVY
    LCD_DisableAllBlock(MAIN_LCD_ID);
    LCD_EnterSleep(MAIN_LCD_ID, FALSE);
    GPIO_SetLcdBackLight(TRUE);
    cfg.end_x = LCD_W - 1;
    cfg.start_x = cfg.end_x + 1 - width;
    cfg.start_y = 0;
    cfg.end_y = cfg.start_y + height - 1;
    cfg.resolution = LCD_RESOLUTION_YUV422;
    if (LCD_RESOLUTION_YUV420 == cfg.resolution)
    cfg.width = width;
    if (LCD_RESOLUTION_YUV422 == cfg.resolution)
    cfg.width = width * 2;
    cfg.colorkey_en = FALSE;
    cfg.alpha_sel = 1;
    cfg.alpha = 0xFF;
    cfg.priority = 0;
    cfg.type = 1; //0:OSD; 1:image
    cfg.rotation = 0;
    if (LCD_RESOLUTION_YUV420 == cfg.resolution)
    {
    LCD_SetBlockBuffer(MAIN_LCD_ID, 0, (uint32*)yuv_addr);
    LCD_SetUVBuffer(MAIN_LCD_ID, 0, (uint32*)(yuv_addr + width * height));//YUV420p
    }
    if (LCD_RESOLUTION_YUV422 == cfg.resolution)
    {
    //LCD_SetBlockBuffer(0, 0, yuv_addr->yaddr);//UYVY
    LCD_SetBlockBuffer(0, 0, yuv_addr);//UYVY
    }
    LCD_SetImageLayerSourceSize(MAIN_LCD_ID, width, height);
    LCD_ConfigBlock(0, 0, cfg);
    LCD_EnableBlock(0, 0);
    LCD_InvalidateRect(0, cfg.start_x, cfg.start_y, cfg.end_x, cfg.end_y);
    }
    void * data
    图像数据
    定义 jrtc.h:180
    volatile char put
    内部使用, 标识图像已更新
    定义 jrtc.h:188
    volatile char get
    外部使用, 标识界面已绘制
    定义 jrtc.h:189
    unsigned short height
    图像高
    定义 jrtc.h:183
  4. UWS6121E平台可能出现定时器内渲染耗时影响性能,可尝试渲染另起线程,起定时器发同步消息给渲染线程的方式
    taskid = SCI_CREATE_THREAD("render", "jc-task-test", OnRender, 1, 0, 1024, 20, 227, SCI_PREEMPT, SCI_DONT_START);
    SCI_ResumeThread(taskid);
    sig_ptr = (RENDER_SIG_T *)malloc(sizeof(RENDER_SIG_T));
    static void OnTimer(uint32 p)
    {
    sig_ptr->command = 222;
    sig_ptr->data = p;
    SCI_TRACE_LOW("render taskid=%d", taskid);
    if (SCI_SUCCESS != SCI_SendSignal((xSignalHeader)sig_ptr, taskid)) {
    SCI_TRACE_LOW("sendsignal failed");
    }
    }
    static void OnRender(void* param)
    {
    RENDER_SIG_T *sig_ptr_t = SCI_NULL;
    JRTC_APPLET_T* applet_ptr = SCI_NULL;
    jrtc_test_t* test = SCI_NULL;
    struct jrtc_image_t* image;
    SCI_TRACE_LOW("onRender");
    while (1) {
    sig_ptr_t = (RENDER_SIG_T *)SCI_GetSignal(taskid);
    if (sig_ptr_t == SCI_NULL)
    continue;
    applet_ptr = (jrtc_test_t*)(sig_ptr_t->data);
    test = &(applet_ptr->test);
    switch (sig_ptr_t->command)
    {
    case 222:
    {
    SCI_TRACE_LOW("match command");
    if (test->testptr) {
    const int state = jrtc_state(test->testptr);
    if (applet_ptr->client_state != state) {
    applet_ptr->client_state = state;
    MMK_PostMsg(applet_ptr->win_handle, MSG_FULL_PAINT, 0, 0);
    }
    if (state < JRTC_JOINED) continue;
    if (test->swap_to_video && test->show_preview && state == JRTC_TALKING)
    {//主叫在接通后,自动切换为视频
    test->show_preview = test->swap_to_video = 0;
    }
    }
    image = test->show_preview ? &test->txframe : &test->rxframe;
    if (image->get != image->put) {
    lcd_show(image);
    image->get = image->put;
    }
    }break;
    default:
    SCI_TRACE_LOW("no match command");
    break;
    }
    }
    }
    jrtc_state
    通话状态
    定义 jrtc.h:411
    @ JRTC_TALKING
    收到媒体后的状态
    定义 jrtc.h:417
    @ JRTC_JOINED
    成功加入会话, 将打开音视频设备
    定义 jrtc.h:416

Unisoc(展锐)Mocor 平台必须的 PDP 流程

Mocor 平台上,创建 socket 需要一个整型值。
因此使用 jrtc_open 前必须对 _jrtc_net_id 赋值,它在 jrtc.h 中声明

extern unsigned _jrtc_net_id;
unsigned _jrtc_net_id
展锐 Mocor 平台 需要设置PDP流程后获得的网络 ID

该值可以由平台默认创建的pdp获取,如下所示:

curNetId = ual_tele_data_get_netid();

编译说明

因为各平台的编译系统完全不同,所以最好 **根据实际情况灵活实现**。
C 语言头文件可以直接放在当前集成代码所在目录。
C 静态库 libjrtc.a 则按各平台的默认情况举例如下:

  1. 将 libjrtc.a 放在 lib 目录
  2. UWS6121E.modules 中添加
    LINKLIBLIST += lib/libjrtc.a