/*********************************************************************************
* Copyright(C),2021, TUYA www.tuya.com

* FileName:		ty_user_rtsp_server.c
* Note			ty_user_rtsp_server api
* Version		V1.0.0
* Data			2021.3
*********************************************************************************/
#include <stdio.h>
#include <string.h>
#include "tuya_ring_buffer.h"
#include "tuya_ipc_media.h"
#include "rtp.h"
#include "rtsp_server.h"

#define MAX_RTSP_USER    5

typedef struct {
    int active;
    IPC_STREAM_E vchn;
    IPC_STREAM_E achn;
    int got_first_frame;
    RING_BUFFER_USER_HANDLE_T v_handle;
    RING_BUFFER_USER_HANDLE_T a_handle;
} rtsp_user_info_s;

static rtsp_user_info_s users[MAX_RTSP_USER] = {0};

static int rtsp_user_start()
{
    int i = 0; 
    for(i = 0; i < MAX_RTSP_USER; i++){
        if (0 == users[i].active){
            users[i].active = 1;
            users[i].vchn = E_IPC_STREAM_MAX;
            users[i].achn = E_IPC_STREAM_MAX;
            users[i].got_first_frame = 0;
            return i;
        }
    }
    return -1;
}

static int rtsp_user_stop(int user_id)
{
    users[user_id].active = 0;
    if (users[user_id].v_handle){
        tuya_ipc_ring_buffer_close(users[user_id].v_handle);
        users[user_id].v_handle = NULL;
    }
    if (users[user_id].a_handle){
        tuya_ipc_ring_buffer_close(users[user_id].a_handle);
        users[user_id].a_handle = NULL;
    }
    return 0;
}

static int rtsp_get_frame(int user_id, RTSP_MEDIA_TYPE_E type, char** buf, int *plen, uint64_t *pts)
{
    rtsp_user_info_s* puser= &users[user_id];
    RING_BUFFER_NODE_T* pnode = NULL;

    if (users[user_id].v_handle == NULL) {
        users[user_id].v_handle = tuya_ipc_ring_buffer_open(0, 0, puser->vchn, E_RBUF_READ);
    }
    if (users[user_id].v_handle == NULL) {
        users[user_id].v_handle = tuya_ipc_ring_buffer_open(0, 0, puser->achn, E_RBUF_READ);
    }

    if (type == RTSP_MEDIA_TYPE_VIDEO){
        pnode = tuya_ipc_ring_buffer_get_frame(users[user_id].v_handle, 0);
    }
    else {
        pnode = tuya_ipc_ring_buffer_get_frame(users[user_id].a_handle, 0);
    }

    if (NULL == pnode){
        return -1;
    }

    *buf = (char *)pnode->raw_data;
    *plen = pnode->size;

    *pts = pnode->timestamp;

    return 0;
}

static int rtsp_get_frame_main(int user_id, RTSP_MEDIA_TYPE_E type, char** buf, int *plen, uint64_t *pts)
{
    users[user_id].vchn = E_IPC_STREAM_VIDEO_MAIN;
    users[user_id].achn = E_IPC_STREAM_AUDIO_MAIN;
    return rtsp_get_frame(user_id, type, buf, plen, pts);
}

static int rtsp_get_frame_sub(int user_id, RTSP_MEDIA_TYPE_E type, char** buf, int *plen, uint64_t *pts)
{
    users[user_id].vchn = E_IPC_STREAM_VIDEO_SUB;
    users[user_id].achn = E_IPC_STREAM_AUDIO_MAIN;
    return rtsp_get_frame(user_id, type, buf, plen, pts);
}

static RTP_CODEC_E get_main_codec(RTSP_MEDIA_TYPE_E type)
{
    switch (type)
    {
    case RTSP_MEDIA_TYPE_VIDEO:
        return RTP_CODEC_H264;
    case RTSP_MEDIA_TYPE_AUDIO:
        return RTP_CODEC_PCM;
    default:
        return 0;
    }
}

static RTP_CODEC_E get_sub_codec(RTSP_MEDIA_TYPE_E type)
{
    switch (type){
    case RTSP_MEDIA_TYPE_VIDEO:
        return RTP_CODEC_H264;
    case RTSP_MEDIA_TYPE_AUDIO:
        return RTP_CODEC_PCM;
    default:
        return 0;
    }
}

static int get_sample_rate(RTSP_MEDIA_TYPE_E type)
{
    switch (type){
    case RTSP_MEDIA_TYPE_VIDEO:
        return 90000;
    case RTSP_MEDIA_TYPE_AUDIO:
        return 8000;
    default:
        return 8000;
    }
}

static int rtsp_get_name_main(char* buf, int* buf_len)
{
    if (buf == NULL)
    {
        return -1;
    }

    strncpy(buf, "stream0", strlen("stream0"));
    return 0;
}

static int rtsp_get_name_sub(char* buf, int* buf_len)
{
    if (buf == NULL)
    {
        return -1;
    }

    strncpy(buf, "stream1", strlen("stream1"));
    return 0;
}

int ty_user_rtsp_server_start(char *pwd)
{
    RTSP_STREAM_SRC_T src[2] = {{0}};
    src[0].get_codec = get_main_codec;
    src[0].get_frame = rtsp_get_frame_main;
    src[0].get_sample_rate = get_sample_rate;
    src[0].start = rtsp_user_start;
    src[0].stop = rtsp_user_stop;
    src[0].get_name = rtsp_get_name_main;

    src[1].get_codec = get_sub_codec;
    src[1].get_frame = rtsp_get_frame_sub;
    src[1].get_sample_rate = get_sample_rate;
    src[1].start = rtsp_user_start;
    src[1].stop = rtsp_user_stop;
    src[1].get_name = rtsp_get_name_sub;

    tuya_ipc_rtsp_server_start("admin", pwd, 8554);
    tuya_ipc_rtsp_server_register_stream_src(src);
    tuya_ipc_rtsp_server_register_stream_src(src + 1);
    return 0;
}

int ty_user_rtsp_server_stop()
{
    tuya_ipc_rtsp_server_stop();
    return 0;
}

int ty_user_rtsp_set_pwd(char *pwd)
{
    int ret = tuya_ipc_rtsp_server_set_password(pwd);
    if (ret != 0)
    {
        return -1;
    }

    return 0;
}
