You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4386 lines
100 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2017-2021. All rights reserved.
* Description: demux mpi func impl.
* Author: Hisilicon
* Create: 2017-06-05
*/
#include <unistd.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include "securec.h"
#include "mpi_demux_ext.h"
#include "mpi_ssm_ext.h"
#include "mpi_memory_ext.h"
#include "soc_errno.h"
#include "soc_log.h"
#include "api_demux_utils.h"
#include "drv_ioctl_demux.h"
#include "securec.h"
/* general macro */
#define DMX_INVALID_PID 0x1FFFU
#define DMX_INVALID_ADDR 0xFFFFFFFF
#define DMX_DEFAULT_PLAYFCT_SIZE (8 * 1024 * 1024)
#define DMX_DEFAULT_RECFCT_SIZE (4 * 1024 * 1024)
#define DMX_DEFAULT_TSBUF_SIZE (2 * 1024 * 1024)
#define SOC_DEV_DEMUX_NAME "soc_demux"
#define DMX_DEV_NAME "/dev/" SOC_DEV_DEMUX_NAME
static td_s32 g_dmx_dev_fd = -1;
static pthread_mutex_t g_dmx_dev_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_pid_lock = PTHREAD_MUTEX_INITIALIZER;
static inline td_s32 dev_opened(td_void)
{
td_s32 ret = SOC_ERR_DMX_NOT_INIT;
if (g_dmx_dev_fd != -1) {
ret = TD_SUCCESS;
} else {
soc_log_err("demux dev not opened.\n");
}
return ret;
}
typedef struct {
td_handle handle;
ext_mpi_dmx_cb_desc raw_cb;
pthread_t context;
} dmx_cb_desc;
struct dmx_play_cb {
dmx_cb_desc cb_desc[DMX_PLAY_CNT];
pthread_t share_context;
td_u32 share_ref;
pthread_mutex_t cb_lock;
};
struct dmx_play_cb g_dmx_play_cb = {};
static td_s32 dmx_mmap(td_handle handle, td_u32 pre_cmd, td_u32 pst_cmd)
{
td_s32 ret;
dmx_pre_mmap_info pre_mmap_info = {
.handle = handle,
};
dmx_pst_mmap_info pst_mmap_info = {
.handle = handle,
};
ret = ioctl(g_dmx_dev_fd, pre_cmd, &pre_mmap_info);
if (ret != TD_SUCCESS) {
/* OUT2DMX will return SOC_ERR_DMX_NOT_SUPPORT. */
if (ret == SOC_ERR_DMX_NOT_SUPPORT) {
ret = TD_SUCCESS;
}
goto out0;
}
pst_mmap_info.usr_addr = mmap(TD_NULL, pre_mmap_info.buf_size, PROT_READ | PROT_WRITE, MAP_SHARED,
(td_s32)pre_mmap_info.buf_handle, 0x0);
if (pst_mmap_info.usr_addr == TD_NULL || pst_mmap_info.usr_addr == (td_void *)DMX_INVALID_ADDR) {
soc_log_err("mmap failed.\n");
ret = TD_FAILURE;
goto out0;
}
ret = ioctl(g_dmx_dev_fd, pst_cmd, &pst_mmap_info);
if (ret != TD_SUCCESS) {
soc_log_err("ioctl pst failed.\n");
goto out1;
}
return TD_SUCCESS;
out1:
if (munmap(pst_mmap_info.usr_addr, pre_mmap_info.buf_size) != 0) {
soc_log_err("munmap failed.\n");
}
if (close((td_s32)pre_mmap_info.buf_handle) != 0) {
soc_log_err("close buf handle failed.\n");
}
out0:
return ret;
}
static td_s32 dmx_unmap(td_handle handle, td_u32 pre_cmd)
{
td_s32 ret;
dmx_pre_mmap_info pre_mmap_info = {
.handle = handle,
};
ret = ioctl(g_dmx_dev_fd, pre_cmd, &pre_mmap_info);
if (ret != TD_SUCCESS) {
goto out;
}
if (pre_mmap_info.usr_addr == TD_NULL || pre_mmap_info.buf_size == 0x0) {
soc_log_warn("buf vir addr is null or buf size is 0, don't need to unmap.\n");
ret = TD_SUCCESS;
goto out;
}
ret = munmap(pre_mmap_info.usr_addr, pre_mmap_info.buf_size);
if (ret != TD_SUCCESS) {
soc_log_err("munmap failed.\n");
goto out;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_init(td_void)
{
td_s32 ret = TD_FAILURE;
td_s32 fd = -1;
td_s32 i;
if (pthread_mutex_lock(&g_dmx_dev_lock) != 0) {
soc_log_err("pthread_mutex_lock failed.\n");
goto out0;
}
if (g_dmx_dev_fd == -1) {
fd = open(DMX_DEV_NAME, O_RDWR, 0);
if (fd < 0) {
soc_log_err("cannot open '%s'\n", DMX_DEV_NAME);
ret = TD_FAILURE;
goto out1;
}
g_dmx_dev_fd = fd;
g_dmx_play_cb.share_context = -1;
g_dmx_play_cb.share_ref = 0;
pthread_mutex_init(&g_dmx_play_cb.cb_lock, TD_NULL);
for (i = 0; i < DMX_PLAY_CNT; i++) {
g_dmx_play_cb.cb_desc[i].context = -1;
g_dmx_play_cb.cb_desc[i].handle = TD_INVALID_HANDLE;
g_dmx_play_cb.cb_desc[i].raw_cb.context_type = EXT_MPI_DMX_CB_CONTEXT_TYPE_MAX;
g_dmx_play_cb.cb_desc[i].raw_cb.chan_buffer_cb = TD_NULL;
g_dmx_play_cb.cb_desc[i].raw_cb.user_data = TD_NULL;
}
ret = TD_SUCCESS;
} else {
soc_log_dbg("demux dev already opened!\n");
ret = TD_SUCCESS;
}
soc_log_dbg("open %s success , g_dmx_dev_fd is %d, fd is %d.\n", DMX_DEV_NAME, g_dmx_dev_fd, fd);
out1:
if (pthread_mutex_unlock(&g_dmx_dev_lock) != 0) {
soc_log_err("pthread_mutex_unlock failed.\n");
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_de_init(td_void)
{
td_s32 ret = TD_FAILURE;
if (pthread_mutex_lock(&g_dmx_dev_lock) != 0) {
soc_log_err("pthread_mutex_lock failed.\n");
goto out0;
}
if (g_dmx_dev_fd != -1) {
if (close(g_dmx_dev_fd) == -1) {
soc_log_err("close %s failed.\n", DMX_DEV_NAME);
goto out1;
}
soc_log_dbg("close %s succeed.\n", DMX_DEV_NAME);
g_dmx_dev_fd = -1;
ret = TD_SUCCESS;
} else {
soc_log_dbg("demux dev not opened.\n");
ret = TD_SUCCESS;
}
out1:
if (pthread_mutex_unlock(&g_dmx_dev_lock) != 0) {
soc_log_err("pthread_mutex_unlock failed.\n");
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_get_capability(dmx_capability *pst_cap)
{
td_s32 ret;
dmx_capability info = {0};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (pst_cap == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_GLB_GETCAP, &info);
if (ret == TD_SUCCESS) {
*pst_cap = info;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_attach_demod(td_u8 demod_id)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_GLB_ATTACH_DEMOD, &demod_id);
if (ret != TD_SUCCESS) {
soc_log_err("set tsi config failed, demod_id(%u).\n", demod_id);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_if_get_port_attrs(dmx_port port, dmx_port_attr *attrs)
{
td_s32 ret;
dmx_get_port_attrs get_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_IF_GETPORTATTRS, &get_attrs);
if (ret == TD_SUCCESS) {
*attrs = get_attrs.attrs;
} else {
soc_log_err("get tsi port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_if_set_port_attrs(dmx_port port, const dmx_port_attr *attrs)
{
td_s32 ret;
dmx_set_port_attrs set_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
set_attrs.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_IF_SETPORTATTRS, &set_attrs);
if (ret != TD_SUCCESS) {
soc_log_err("set if port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_tsi_get_port_attrs(dmx_port port, dmx_port_attr *attrs)
{
td_s32 ret;
dmx_get_port_attrs get_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_TSI_GETPORTATTRS, &get_attrs);
if (ret == TD_SUCCESS) {
*attrs = get_attrs.attrs;
} else {
soc_log_err("get tsi port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_tsi_set_port_attrs(dmx_port port, const dmx_port_attr *attrs)
{
td_s32 ret;
dmx_set_port_attrs set_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
set_attrs.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_TSI_SETPORTATTRS, &set_attrs);
if (ret != TD_SUCCESS) {
soc_log_err("set tsi port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_tso_get_port_attrs(dmx_port port, dmx_tso_port_attr *attrs)
{
td_s32 ret;
dmx_get_tso_port_attrs get_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_TSO_GETPORTATTRS, &get_attrs);
if (ret == TD_SUCCESS) {
*attrs = get_attrs.attrs;
} else {
soc_log_err("get tso port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_tso_set_port_attrs(dmx_port port, const dmx_tso_port_attr *attrs)
{
td_s32 ret;
dmx_set_tso_port_attrs set_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
set_attrs.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_TSO_SETPORTATTRS, &set_attrs);
if (ret != TD_SUCCESS) {
soc_log_err("set tsi port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_tag_get_port_attrs(dmx_port port, dmx_tag_port_attr *attrs)
{
td_s32 ret;
dmx_get_tag_port_attrs get_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_TAG_GETPORTATTRS, &get_attrs);
if (ret == TD_SUCCESS) {
*attrs = get_attrs.attrs;
} else {
soc_log_err("get tag port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_tag_set_port_attrs(dmx_port port, const dmx_tag_port_attr *attrs)
{
td_s32 ret;
dmx_set_tag_port_attrs set_attrs = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
set_attrs.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_TAG_SETPORTATTRS, &set_attrs);
if (ret != TD_SUCCESS) {
soc_log_err("set tag port attrs failed, port(%u).\n", port);
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_ram_get_port_default_attrs(dmx_ram_port_attr *attrs)
{
td_s32 ret = TD_FAILURE;
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
attrs->secure_mode = DMX_SECURE_NONE;
attrs->buffer_size = DMX_DEFAULT_TSBUF_SIZE; /* 2mi_b */
attrs->max_data_rate = DMX_DEFAULT_RAMPORT_RATE; /* kpbs: best efford with auto flow control. */
ret = TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_open_port(dmx_port port, const dmx_ram_port_attr *attrs, td_handle *handle)
{
td_s32 ret;
dmx_open_ram_port_info info = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if ((attrs == TD_NULL) || (handle == TD_NULL)) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_OPENPORT, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_RAM_OPENPORT failed, ret[0x%x].\n", ret);
goto out0;
}
if (attrs->secure_mode != DMX_SECURE_TEE) {
ret = dmx_mmap(info.handle, DMX_IOCTL_RAM_PREMMAP, DMX_IOCTL_RAM_PSTMMAP);
if (ret != TD_SUCCESS) {
soc_log_err("dmx_mmap failed, ret[0x%x].\n", ret);
goto out1;
}
}
*handle = info.handle;
return TD_SUCCESS;
out1:
ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_CLOSEPORT, &info.handle);
out0:
return ret;
}
td_s32 ext_mpi_dmx_ram_get_port_attrs(td_handle handle, dmx_port_attr *attrs)
{
td_s32 ret;
dmx_get_ram_port_attrs info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_GETPORTATTRS, &info);
if (ret == TD_SUCCESS) {
*attrs = info.attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_set_port_attrs(td_handle handle, const dmx_port_attr *attrs)
{
td_s32 ret;
dmx_set_ram_port_attrs info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_SETPORTATTRS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_get_port_status(td_handle handle, dmx_ram_port_status *status)
{
td_s32 ret;
dmx_get_ram_port_status_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (status == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_GETPORTSTATUS, &info);
if (ret == TD_SUCCESS) {
*status = info.status;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_get_buffer(td_handle handle, td_u32 req_len, dmx_ram_buffer *buf, td_u32 time_out) /* ms */
{
td_s32 ret;
dmx_get_ram_buffer_info info = {
.handle = handle,
.req_len = req_len,
.time_out = time_out,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (req_len == 0 || buf == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_GETBUFFER, &info);
if (ret == TD_SUCCESS) {
*buf = info.buf;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_push_buffer(td_handle handle, const dmx_ram_buffer *buf)
{
td_s32 ret;
dmx_push_ram_buffer_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (buf == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.buf = *buf;
restart:
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_PUSHBUFFER, &info);
if (ret == SOC_ERR_DMX_INTR) {
soc_log_warn("push failed, try again!\n");
goto restart;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_put_buffer(td_handle handle, td_u32 valid_datalen, td_u32 start_pos)
{
td_s32 ret;
dmx_put_ram_buffer_info info = {
.handle = handle,
.valid_datalen = valid_datalen,
.start_pos = start_pos
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_PUTBUFFER, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_release_buffer(td_handle handle, const dmx_ram_buffer *buf)
{
td_s32 ret;
dmx_release_ram_buffer_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (buf == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.buf = *buf;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_RELEASEBUFFER, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_flush_buffer(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_FLUSHBUFFER, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_reset_buffer(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_RESETBUFFER, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_close_port(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = dmx_unmap(handle, DMX_IOCTL_RAM_PREMMAP);
if (ret != TD_SUCCESS) {
soc_log_err("unmap mem failed, ret(%d).\n", ret);
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_CLOSEPORT, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_ram_get_port_id(td_handle handle, dmx_port *port)
{
td_s32 ret;
dmx_get_ram_portid_info info = {
.handle = handle,
};
if (port == TD_NULL) {
soc_log_err("invalid parameter.\n");
return SOC_ERR_DMX_INVALID_PARA;
}
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_GETPORTID, &info);
if (ret == TD_SUCCESS) {
*port = info.port;
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_ram_get_handle(dmx_port port, td_handle *handle)
{
td_s32 ret;
dmx_get_ram_porthandle_info info = {
.port = port,
};
if (handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
return SOC_ERR_DMX_INVALID_PARA;
}
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_GETPORTHANDLE, &info);
if (ret == TD_SUCCESS) {
*handle = info.handle;
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_ram_attach_ssm(td_handle handle, td_handle ssm, dmx_buffer_attach_type attach_type)
{
td_s32 ret;
td_u64 sec_info_addr;
dmx_get_ram_buf_handle handle_info = {0};
ext_ssm_buffer_attach_info attach_info = {0};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attach_type >= EXT_DMX_BUFFER_ATTACH_MAX) {
soc_log_err("Invalid attach type %u.\n", attach_type);
return SOC_ERR_DMX_INVALID_PARA;
}
handle_info.handle = handle;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RAM_GETBUFHANDLE, &handle_info);
if (ret != TD_SUCCESS) {
soc_log_err("get buf handle failed,ssm[%#x] attach type[%#u] ret[%x].\n", ssm, attach_type, ret);
goto out;
}
attach_info.dma_buf_handle = (td_handle)handle_info.dsc_buf_handle;
attach_info.buf_id = EXT_SSM_BUFFER_ID_INTERNAL_BUF_DMX;
attach_info.module_handle = handle;
attach_info.session_handle = ssm;
ret = ext_mpi_ssm_attach_buffer(&attach_info, &sec_info_addr);
if (ret != TD_SUCCESS) {
soc_log_err("attach secure dsc buffer failed, bufhandle[%#x].\n", attach_info.dma_buf_handle);
goto out;
}
attach_info.dma_buf_handle = (td_handle)handle_info.flush_buf_handle;
attach_info.buf_id = EXT_SSM_BUFFER_ID_INTERNAL_BUF_DMX;
attach_info.module_handle = handle;
attach_info.session_handle = ssm;
ret = ext_mpi_ssm_attach_buffer(&attach_info, &sec_info_addr);
if (ret != TD_SUCCESS) {
soc_log_err("attach secure flush buffer failed, bufhandle[%#x].\n", attach_info.dma_buf_handle);
goto out;
}
attach_info.dma_buf_handle = (td_handle)handle_info.buf_handle;
attach_info.buf_id = (attach_type == EXT_DMX_BUFFER_ATTACH_TSR2RCIPHER) ?
EXT_SSM_BUFFER_ID_PVR_PLAYBACK_TS_BUF : EXT_SSM_BUFFER_ID_MCIPHER_TS_BUF;
attach_info.module_handle = handle;
attach_info.session_handle = ssm;
ret = ext_mpi_ssm_attach_buffer(&attach_info, &sec_info_addr);
if (ret != TD_SUCCESS) {
soc_log_err("attach secure ts buffer failed, bufhandle[%#x].\n", attach_info.dma_buf_handle);
}
out:
return ret;
}
td_s32 ext_mpi_dmx_get_ts_port_packet_num(dmx_port port, dmx_port_packet_num *port_stat)
{
td_s32 ret;
dmx_port_packet_info info = {
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (port_stat == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_GLB_GET_PACKETNUM, &info);
if (ret == TD_SUCCESS) {
*port_stat = info.port_stat;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_band_open(dmx_band band, const dmx_band_attr *attrs, td_handle *handle)
{
td_s32 ret;
dmx_open_band_info info = {
.band = band,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL || handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_OPEN, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_BAND_OPEN failed, ret[0x%x].\n", ret);
goto out;
}
*handle = info.handle;
return TD_SUCCESS;
out:
return ret;
}
/* attention: ext_mpi_dmx_band_ref_inc just used for keep adaptive the iapi function */
td_s32 ext_mpi_dmx_band_ref_inc(dmx_band band, const dmx_band_attr *attrs, td_handle *handle)
{
td_s32 ret;
dmx_open_band_info info = {
.band = band,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL || handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_REFINC, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_BAND_REFINC failed, ret[0x%x].\n", ret);
goto out;
}
*handle = info.handle;
return TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_band_attach_port(td_handle handle, dmx_port port)
{
td_s32 ret;
dmx_band_attach_port_info info = {
.handle = handle,
.port = port,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_ATTACHPORT, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_band_detach_port(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_DETACHPORT, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_band_get_attrs(td_handle handle, dmx_band_attr *attrs)
{
td_s32 ret;
dmx_get_band_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_GETATTRS, &info);
if (ret == TD_SUCCESS) {
*attrs = info.attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_band_set_attrs(td_handle handle, const dmx_band_attr *attrs)
{
td_s32 ret;
dmx_set_band_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_SETATTRS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_band_get_status(td_handle handle, dmx_band_status *status)
{
td_s32 ret;
dmx_get_band_status_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (status == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_GETSTATUS, &info);
if (ret == TD_SUCCESS) {
*status = info.status;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_band_close(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_CLOSE, &handle);
out:
return ret;
}
/* attention: ext_mpi_dmx_band_ref_dec just used for keep adaptive the iapi function */
td_s32 ext_mpi_dmx_band_ref_dec(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_REFDEC, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_pid_ch_create(td_handle band_handle, td_u32 pid, td_handle *handle)
{
td_s32 ret;
dmx_create_pid_ch_info info = {
.band_handle = band_handle,
.pid = pid,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_CREATE, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PIDCHANNEL_CREATE failed, ret[0x%x].\n", ret);
goto out;
}
*handle = info.handle;
return TD_SUCCESS;
out:
return ret;
}
/* attention: ext_mpi_dmx_pid_ch_ref_inc just used for keep adaptive the iapi function */
td_s32 ext_mpi_dmx_pid_ch_ref_inc(td_handle band_handle, td_u32 pid, td_handle *handle)
{
td_s32 ret;
dmx_create_pid_ch_info info = {
.band_handle = band_handle,
.pid = pid,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (handle == TD_NULL) {
soc_log_err("Invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_REFINC, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PIDCHANNEL_REFINC failed, ret[0x%x].\n", ret);
goto out;
}
*handle = info.handle;
return TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_pid_ch_get_handle_by_pid(td_handle band_handle, td_u32 pid, td_handle *handle)
{
td_s32 ret;
dmx_get_pid_ch_handle_info info = {
.band_handle = band_handle,
.pid = pid,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_GETHANDLE, &info);
if (ret != TD_SUCCESS) {
soc_log_warn("DMX_IOCTL_PIDCHANNEL_GETHANDLE failed, ret[0x%x].\n", ret);
goto out;
}
*handle = info.handle;
return TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_pid_ch_get_status(td_handle handle, dmx_pidch_status *status)
{
td_s32 ret;
dmx_get_pid_ch_status_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (status == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_GETSTATUS, &info);
if (ret == TD_SUCCESS) {
*status = info.status;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_pid_ch_lock_out(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_LOCKOUT, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_pid_ch_un_lock_out(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_UNLOCKOUT, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_pid_ch_destroy(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_DESTROY, &handle);
out:
return ret;
}
/* attention: ext_mpi_dmx_pid_ch_ref_dec just used for keep adaptive the iapi function */
td_s32 ext_mpi_dmx_pid_ch_ref_dec(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_REFDEC, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_pid_ch_get_free_cnt(td_u32 dmx_id, td_u32 *free_cnt)
{
td_s32 ret;
td_u32 cnt = 0;
TD_UNUSED(dmx_id);
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (free_cnt == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PIDCHANNEL_GETFREECNT, &cnt);
*free_cnt = cnt;
out:
return ret;
}
static td_s32 mpi_dmx_play_check_attrs(const dmx_play_attrs *attrs)
{
td_s32 ret = SOC_ERR_DMX_INVALID_PARA;
if (attrs->buf_size < DMX_PLAY_MIN_BUFFER_SIZE || attrs->buf_size > DMX_PLAY_MAX_BUFFER_SIZE) {
soc_log_err("invalid play buffer size(0x%x)\n", attrs->buf_size);
goto out;
}
if (attrs->type < DMX_PLAY_TYPE_SEC || attrs->type > DMX_PLAY_TYPE_TS) {
soc_log_err("invalid play type(0x%x)\n", attrs->type);
goto out;
}
if (attrs->crc_mode < DMX_FLT_CRC_MODE_FORBID || attrs->crc_mode > DMX_FLT_CRC_MODE_BY_SYNTAX_AND_SEND) {
soc_log_err("invalid CRC mode(0x%x)\n", attrs->crc_mode);
goto out;
}
return TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_default_attrs(dmx_play_attrs *attrs)
{
td_s32 ret = TD_FAILURE;
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
attrs->type = DMX_PLAY_TYPE_TS;
attrs->vcodec_type = DMX_VCODEC_TYPE_MAX;
attrs->crc_mode = DMX_FLT_CRC_MODE_FORCE_AND_DISCARD;
attrs->live_play = TD_TRUE;
attrs->data_mode = DMX_DATA_MODE_STREAM;
attrs->secure_mode = DMX_SECURE_NONE;
attrs->buf_size = DMX_DEFAULT_PLAYFCT_SIZE; /* 8MB */
ret = TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_play_create(const dmx_play_attrs *attrs, td_handle *handle)
{
td_s32 ret;
dmx_create_play_fct_info info;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL || handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
ret = mpi_dmx_play_check_attrs(attrs);
if (ret != TD_SUCCESS) {
soc_log_err("invalid play attrs.\n");
goto out0;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_CREATE, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PLAYFCT_CREATE failed, ret[0x%x].\n", ret);
goto out0;
}
if ((attrs->secure_mode != DMX_SECURE_TEE) ||
((attrs->type == DMX_PLAY_TYPE_SEC) || (attrs->type == DMX_PLAY_TYPE_PES))) {
ret = dmx_mmap(info.handle, DMX_IOCTL_PLAYFCT_PREMMAP, DMX_IOCTL_PLAYFCT_PSTMMAP);
if (ret != TD_SUCCESS) {
soc_log_err("dmx_mmap failed, ret[0x%x].\n", ret);
goto out1;
}
}
*handle = info.handle;
return TD_SUCCESS;
out1:
ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_DESTROY, &info.handle);
out0:
return ret;
}
td_s32 ext_mpi_dmx_play_open(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_OPEN, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_attrs(td_handle handle, dmx_play_attrs *attrs)
{
td_s32 ret;
dmx_get_play_fct_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GETATTRS, &info);
if (ret == TD_SUCCESS) {
*attrs = info.attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_set_attrs(td_handle handle, const dmx_play_attrs *attrs)
{
td_s32 ret;
dmx_set_play_fct_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_SETATTRS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_set_eos_flag(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_SETEOS, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_status(td_handle handle, dmx_play_status *status)
{
td_s32 ret;
dmx_get_play_fct_status_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (status == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GETSTATUS, &info);
if (ret == TD_SUCCESS) {
*status = info.status;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_packet_num(td_handle handle, dmx_chan_packet_num *chn_stat)
{
td_s32 ret;
dmx_get_play_fct_packet_info info = {
.handle = handle
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (chn_stat == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GETPACKET, &info);
if (ret == TD_SUCCESS) {
*chn_stat = info.chn_stat;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_scrambled_flag(td_handle handle, ext_dmx_scrambled_flag *scramble_flag)
{
td_s32 ret;
dmx_play_fct_get_scrambled_flag_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (scramble_flag == TD_NULL) {
soc_log_err("invalid parameter, null ptr.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GET_SCRAMBLEDFLAG, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PLAYFCT_GET_SCRAMBLEDFLAG failed, ret[0x%x].\n", ret);
goto out;
}
*scramble_flag = info.scramble_flag;
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_pid_ch(td_handle handle, td_handle *ch_handle)
{
td_s32 ret;
dmx_play_fct_get_pid_ch_info info = {
.handle = handle,
};
if (ch_handle == TD_NULL) {
soc_log_err("invalid para!\n");
return SOC_ERR_DMX_INVALID_PARA;
}
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GETPIDCH, &info);
if (ret != TD_SUCCESS) {
soc_log_warn("DMX_IOCTL_PLAYFCT_GETPIDCH failed, ret[0x%x].\n", ret);
goto out;
}
*ch_handle = info.pid_ch_handle;
out:
return ret;
}
/* need flash hardware data */
td_s32 ext_mpi_dmx_play_attach_pid_ch(td_handle handle, td_handle ch_handle)
{
td_s32 ret;
dmx_play_fct_attach_pid_ch_info info = {
.handle = handle,
.pid_ch_handle = ch_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_ATTACHPIDCH, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_detach_pid_ch(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_DETACHPIDCH, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_create_filter(const dmx_filter_attrs *attrs, td_handle *flt_handle)
{
td_s32 ret;
dmx_play_fct_create_flt_info info;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL || flt_handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_CREATEFILTER, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PLAYFCT_CREATEFILTER failed, ret[0x%x].\n", ret);
goto out;
}
*flt_handle = info.flt_handle;
out:
return ret;
}
td_s32 ext_mpi_dmx_play_add_filter(td_handle handle, td_handle flt_handle)
{
td_s32 ret;
dmx_play_fct_add_flt_info info = {
.handle = handle,
.flt_handle = flt_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_ADDFILTER, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PLAYFCT_ADDFILTER failed, ret[0x%x].\n", ret);
goto out;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_del_filter(td_handle handle, td_handle flt_handle)
{
td_s32 ret;
dmx_play_fct_del_flt_info info = {
.handle = handle,
.flt_handle = flt_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_DELFILTER, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_del_all_filter(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_DELALLFILTER, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_update_filter(td_handle flt_handle, const dmx_filter_attrs *attrs)
{
td_s32 ret;
dmx_play_fct_update_flt_info info = {
.flt_handle = flt_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_UPDATEFILTER, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_filter(td_handle flt_handle, dmx_filter_attrs *attrs)
{
td_s32 ret;
dmx_play_fct_get_flt_info info = {
.flt_handle = flt_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GETFILTER, &info);
if (ret == TD_SUCCESS) {
*attrs = info.attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_handle_by_filter(td_handle flt_handle, td_handle *play_handle)
{
td_s32 ret;
dmx_play_fct_get_handle_info info = {
.flt_handle = flt_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (play_handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GETHANDLE, &info);
if (ret == TD_SUCCESS) {
*play_handle = info.play_handle;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_free_filter_cnt(td_u32 dmx_id, td_u32 *free_cnt)
{
td_s32 ret;
td_u32 free_flt_cnt = 0;
TD_UNUSED(dmx_id);
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (free_cnt == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GET_FREEFLT_CNT, &free_flt_cnt);
if (ret == TD_SUCCESS) {
*free_cnt = free_flt_cnt;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_destroy_filter(td_handle flt_handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_DESTROYFILTER, &flt_handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_get_data_handle(td_handle *channel_array, td_u32 *ch_num, td_u32 time_out_ms)
{
td_s32 ret;
dmx_get_data_flag param;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if ((channel_array == TD_NULL) || (ch_num == TD_NULL)) {
soc_log_err("Null pointer channel_array or ch_num\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
if (*ch_num == 0 || *ch_num > DMX_PLAY_CNT) {
soc_log_err("Invalid channel number:%d\n", *ch_num);
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
param.watch_num = *ch_num;
param.valid_channel = channel_array;
param.valid_num = ch_num;
param.time_out_ms = time_out_ms;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GET_DATAHANDLE, &param);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_select_data_handle(td_handle *watch_channel, td_u32 watch_num,
td_handle *data_channel, td_u32 *valid_num, td_u32 time_out_ms)
{
td_s32 ret;
dmx_select_data_flag param;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if ((watch_channel == TD_NULL) || (data_channel == TD_NULL) || (valid_num == TD_NULL)) {
soc_log_err("Null pointer, watch_channel or data_channel or valid_num.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
if (watch_num == 0) {
soc_log_err("Invalid channel number:%d\n", watch_num);
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
param.watch_array = watch_channel;
param.watch_num = watch_num;
param.valid_channel = data_channel;
param.valid_num = valid_num;
param.time_out_ms = time_out_ms;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_SELECT_DATAHANDLE, &param);
out:
return ret;
}
static dmx_cb_desc *play_get_cb_desc_by_handle(td_handle handle)
{
td_s32 i;
for (i = 0; i < DMX_PLAY_CNT; i++) {
if (handle == g_dmx_play_cb.cb_desc[i].handle) {
return &g_dmx_play_cb.cb_desc[i];
}
}
return TD_NULL;
}
#define PLAY_CB_THREAD_TIMEOUT 200
static td_s32 play_cb_thread_recv_data(td_handle handle, ext_mpi_dmx_chan_buf_cb_func cb_func, td_void *user_data,
td_u32 user_data_len)
{
td_s32 ret;
ext_mpi_dmx_data acqed_msg_buf;
dmx_buffer buf = {0};
td_u32 acqed_num = 0;
dmx_play_status status = {0};
/* Reduce the probability of channel being destroyed when acquiring buffer */
ret = ext_mpi_dmx_play_get_status(handle, &status);
if (ret != TD_SUCCESS) {
goto err_exit;
}
if (status.is_opened == TD_FALSE) {
ret = SOC_ERR_DMX_NOT_OPEN_CHAN;
goto err_exit;
}
ret = ext_mpi_dmx_play_acquire_buf(handle, 1, &acqed_num, &buf, PLAY_CB_THREAD_TIMEOUT);
if (ret != TD_SUCCESS) {
soc_log_err("acquire cb data failed(0x%x).\n", ret);
goto err_exit;
}
acqed_msg_buf.data = buf.data;
acqed_msg_buf.size = buf.length;
acqed_msg_buf.data_type = (td_u32)buf.data_type;
cb_func(handle, acqed_num, &acqed_msg_buf, user_data, user_data_len);
/* Reduce the probability of channel being destroyed when release buffer */
ret = ext_mpi_dmx_play_get_status(handle, &status);
if (ret != TD_SUCCESS) {
goto err_exit;
}
if (status.is_opened == TD_FALSE) {
ret = SOC_ERR_DMX_NOT_OPEN_CHAN;
goto err_exit;
}
ret = ext_mpi_dmx_play_release_buf(handle, acqed_num, &buf);
if (ret != TD_SUCCESS) {
soc_log_err("release cb data failed(0x%x).\n", ret);
goto err_exit;
}
return TD_SUCCESS;
err_exit:
return ret;
}
static td_void play_proc_each_set(td_handle set)
{
td_handle handle;
ext_mpi_dmx_cb_context_type context_type;
ext_mpi_dmx_chan_buf_cb_func cb_func;
td_void *user_data = TD_NULL;
td_u32 user_data_len;
dmx_cb_desc *cb_desc = TD_NULL;
if (pthread_mutex_lock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("pthread_mutex_lock failed, continue...\n");
return;
}
cb_desc = play_get_cb_desc_by_handle(set);
if (cb_desc != TD_NULL) {
handle = cb_desc->handle;
context_type = cb_desc->raw_cb.context_type;
cb_func = cb_desc->raw_cb.chan_buffer_cb;
user_data = cb_desc->raw_cb.user_data;
user_data_len = cb_desc->raw_cb.user_data_len;
}
if (pthread_mutex_unlock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("pthread_mutex_unlock failed.\n");
}
if (cb_desc == TD_NULL) {
/* if other thread unregister the callback, call play_get_cb_desc_by_handle will return null. */
soc_log_err("get cb desc failed.\n");
return;
}
if ((context_type == EXT_MPI_DMX_CB_CONTEXT_TYPE_SHARED) && (cb_func != TD_NULL)) {
if (play_cb_thread_recv_data(handle, cb_func, user_data, user_data_len) != TD_SUCCESS) {
soc_log_dbg("call play_cb_thread_recv_data failed!\n");
}
}
return;
}
static td_void *play_shared_cb_thread(td_void *args)
{
td_s32 ret;
dmx_cb_desc *cb_desc = TD_NULL;
td_handle watch_set[DMX_PLAY_CNT] = {0};
td_u32 watch_cnt;
td_handle valid_set[DMX_PLAY_CNT] = {0};
td_u32 valid_cnt = 0;
TD_UNUSED(args);
for (;;) {
td_u32 index;
watch_cnt = 0;
if (pthread_mutex_lock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("pthread_mutex_lock failed, continue...\n");
continue;
}
for (index = 0; index < DMX_PLAY_CNT; index++) {
cb_desc = &g_dmx_play_cb.cb_desc[index];
if (cb_desc->handle != TD_INVALID_HANDLE &&
cb_desc->raw_cb.context_type == EXT_MPI_DMX_CB_CONTEXT_TYPE_SHARED) {
watch_set[watch_cnt] = cb_desc->handle;
watch_cnt++;
}
}
if (pthread_mutex_unlock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("pthread_mutex_unlock failed.\n");
}
if (watch_cnt == 0) {
break;
}
ret = ext_mpi_dmx_play_select_data_handle(watch_set, watch_cnt, valid_set, &valid_cnt, PLAY_CB_THREAD_TIMEOUT);
if (ret != TD_SUCCESS) {
continue;
}
for (index = 0; index < valid_cnt; index++) {
play_proc_each_set(valid_set[index]);
}
}
return TD_NULL;
}
static td_void *play_private_cb_thread(td_void *args)
{
td_s32 ret;
dmx_cb_desc *cb_desc = (dmx_cb_desc *)args;
for (;;) {
td_handle handle;
ext_mpi_dmx_cb_context_type context_type;
ext_mpi_dmx_chan_buf_cb_func cb_func;
td_void *user_data = TD_NULL;
td_u32 user_data_len;
if (pthread_mutex_lock(&g_dmx_play_cb.cb_lock) == 0) {
handle = cb_desc->handle;
context_type = cb_desc->raw_cb.context_type;
cb_func = cb_desc->raw_cb.chan_buffer_cb;
user_data = cb_desc->raw_cb.user_data;
user_data_len = cb_desc->raw_cb.user_data_len;
if (pthread_mutex_unlock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("pthread_mutex_unlock failed.\n");
}
} else {
soc_log_err("pthread_mutex_lock failed, continue...\n");
continue;
}
if ((handle != TD_INVALID_HANDLE) &&
(context_type == EXT_MPI_DMX_CB_CONTEXT_TYPE_PRIVATE) && (cb_func != TD_NULL)) {
ret = play_cb_thread_recv_data(handle, cb_func, user_data, user_data_len);
if (ret != TD_SUCCESS) {
continue;
}
} else {
break;
}
}
return TD_NULL;
}
static td_s32 dmx_play_get_not_used_id(td_handle handle, td_s32 *index)
{
td_s32 i;
for (i = 0; i < DMX_PLAY_CNT; i++) {
if (g_dmx_play_cb.cb_desc[i].handle == handle) {
soc_log_err("can't repeat set cb, handle %u.\n", handle);
return SOC_ERR_DMX_BUSY;
}
}
for (i = 0; i < DMX_PLAY_CNT; i++) {
if (g_dmx_play_cb.cb_desc[i].handle == TD_INVALID_HANDLE) {
break;
}
}
if (i >= DMX_PLAY_CNT) {
soc_log_err("can't find free cb desc, %d.\n", i);
return TD_FAILURE;
}
*index = i;
return TD_SUCCESS;
}
static td_s32 dmx_play_set_cb(td_handle handle, const ext_mpi_dmx_cb_desc *cb_desc, td_s32 index)
{
td_s32 i = index;
g_dmx_play_cb.cb_desc[i].handle = handle;
g_dmx_play_cb.cb_desc[i].raw_cb = *cb_desc;
if (g_dmx_play_cb.cb_desc[i].raw_cb.context_type == EXT_MPI_DMX_CB_CONTEXT_TYPE_SHARED) {
if (g_dmx_play_cb.share_context == -1) {
if (pthread_create(&g_dmx_play_cb.share_context, TD_NULL, play_shared_cb_thread, TD_NULL) != 0) {
g_dmx_play_cb.share_context = -1;
soc_log_err("create share ctx thread failed,\n");
return TD_FAILURE;
}
}
g_dmx_play_cb.share_ref++;
} else if (g_dmx_play_cb.cb_desc[i].raw_cb.context_type == EXT_MPI_DMX_CB_CONTEXT_TYPE_PRIVATE) {
if (pthread_create(&g_dmx_play_cb.cb_desc[i].context,
TD_NULL, play_private_cb_thread, (td_void *)&g_dmx_play_cb.cb_desc[i]) != 0) {
g_dmx_play_cb.cb_desc[i].context = -1;
soc_log_err("create private ctx thread failed,\n");
return TD_FAILURE;
}
}
return TD_SUCCESS;
}
static td_s32 dmx_play_attr_check(td_handle handle, const ext_mpi_dmx_cb_desc *cb_desc)
{
td_s32 ret;
dmx_play_attrs attrs;
if (cb_desc->context_type >= EXT_MPI_DMX_CB_CONTEXT_TYPE_MAX || cb_desc->chan_buffer_cb == TD_NULL) {
soc_log_err("invalid param or cb is null, %u\n", cb_desc->context_type);
return TD_FAILURE;
}
ret = ext_mpi_dmx_play_get_attrs(handle, &attrs);
if (ret != TD_SUCCESS) {
soc_log_err("get play fct attrs failed, handle(%u).\n", handle);
return ret;
}
if (attrs.type == DMX_PLAY_TYPE_AUD || attrs.type == DMX_PLAY_TYPE_VID) {
soc_log_err("aud or vid play fct not support register cb, handle %u, type %u.\n", handle, attrs.type);
return SOC_ERR_DMX_INVALID_PARA;
}
return TD_SUCCESS;
}
td_s32 ext_mpi_dmx_play_register_callback(td_handle handle, const ext_mpi_dmx_cb_desc *cb_desc)
{
td_s32 ret;
td_s32 i;
ret = dev_opened();
if (ret != TD_SUCCESS) {
return TD_FAILURE;
}
if (cb_desc == TD_NULL) {
soc_log_err("null pointer.\n");
return SOC_ERR_DMX_NULL_PTR;
}
ret = check_handle(handle);
if (ret != TD_SUCCESS) {
soc_log_err("invalid parameter.\n");
return SOC_ERR_DMX_INVALID_PARA;
}
ret = dmx_play_attr_check(handle, cb_desc);
if (ret != TD_SUCCESS) {
goto out0;
}
if (pthread_mutex_lock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("lock mutex failed.\n");
ret = TD_FAILURE;
goto out0;
}
ret = dmx_play_get_not_used_id(handle, &i);
if (ret != TD_SUCCESS) {
goto out1;
}
ret = dmx_play_set_cb(handle, cb_desc, i);
if (ret != TD_SUCCESS) {
goto out2;
}
if (pthread_mutex_unlock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("unlock mutex failed.\n");
}
return TD_SUCCESS;
out2:
g_dmx_play_cb.cb_desc[i].handle = TD_INVALID_HANDLE;
out1:
if (pthread_mutex_unlock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("unlock mutex failed.\n");
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_play_unregister_callback(td_handle handle)
{
td_s32 ret;
pthread_t saved_shared_context = -1;
pthread_t saved_private_context = -1;
dmx_cb_desc *cb_desc = TD_NULL;
if (dev_opened() != TD_SUCCESS) {
return TD_FAILURE;
}
ret = check_handle(handle);
if (ret != TD_SUCCESS) {
soc_log_err("invalid parameter.\n");
return SOC_ERR_DMX_INVALID_PARA;
}
if (pthread_mutex_lock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("pthread_mutex_lock failed.\n");
return TD_FAILURE;
}
cb_desc = play_get_cb_desc_by_handle(handle);
if (cb_desc == TD_NULL) {
/* if not register call unregister return success. */
soc_log_dbg("get cb desc failed.\n");
if (pthread_mutex_unlock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("unlock mutex failed.\n");
}
return TD_SUCCESS;
}
if (cb_desc->raw_cb.context_type == EXT_MPI_DMX_CB_CONTEXT_TYPE_SHARED) {
g_dmx_play_cb.share_ref--;
saved_shared_context = (g_dmx_play_cb.share_ref == 0) ? g_dmx_play_cb.share_context : saved_shared_context;
g_dmx_play_cb.share_context = (g_dmx_play_cb.share_ref == 0) ? -1 : g_dmx_play_cb.share_context;
} else if (cb_desc->raw_cb.context_type == EXT_MPI_DMX_CB_CONTEXT_TYPE_PRIVATE) {
saved_private_context = cb_desc->context;
}
cb_desc->context = -1;
cb_desc->handle = TD_INVALID_HANDLE;
cb_desc->raw_cb.context_type = EXT_MPI_DMX_CB_CONTEXT_TYPE_MAX;
cb_desc->raw_cb.chan_buffer_cb = TD_NULL;
cb_desc->raw_cb.user_data = TD_NULL;
if (pthread_mutex_unlock(&g_dmx_play_cb.cb_lock) != 0) {
soc_log_err("unlock mutex failed.\n");
}
if (saved_shared_context != -1) {
pthread_join(saved_shared_context, TD_NULL);
}
if (saved_private_context != -1) {
pthread_join(saved_private_context, TD_NULL);
}
return TD_SUCCESS;
}
td_s32 ext_mpi_dmx_play_peek_buf(td_handle handle, td_u32 peek_num, td_u32 *peeked_num,
dmx_buffer *buf, td_u32 time_out)
{
td_s32 ret;
dmx_play_fct_acquire_buf_info info = {
.handle = handle,
.acq_num = peek_num,
.time_out = time_out,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (buf == TD_NULL || peeked_num == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.play_fct_buf = buf;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_PEEK_BUF, &info);
if (ret == TD_SUCCESS) {
*peeked_num = info.acqed_num;
}
out:
return ret;
}
static td_s32 dmx_play_is_v1r6_pes_chan(td_handle chan, td_bool *is_v1r6_pes_chan)
{
td_s32 ret;
ext_sys_version version;
*is_v1r6_pes_chan = TD_FALSE;
ret = dmx_api_utils_get_chip_version(&version);
if (ret != TD_SUCCESS) {
return ret;
}
if ((version.chip_name_id == CHIP_NAME_RESERVED5) || (version.chip_name_id == CHIP_NAME_RESERVED2) ||
(version.chip_name_id == CHIP_NAME_RESERVED17) || (version.chip_name_id == CHIP_NAME_RESERVED19) ||
(version.chip_name_id == CHIP_NAME_HI3751V811)) {
dmx_play_attrs chan_attrs;
ret = ext_mpi_dmx_play_get_attrs(chan, &chan_attrs);
if (ret != TD_SUCCESS) {
soc_log_err("get chan attrs failed. ret = 0x%x\n", ret);
return ret;
}
*is_v1r6_pes_chan = (chan_attrs.type == DMX_PLAY_TYPE_PES) ? TD_TRUE : TD_FALSE;
}
return TD_SUCCESS;
}
static td_s32 dmx_play_check_pes_user_msg(const dmx_buffer *pst_buf, td_u32 buff_size)
{
td_u32 head_type, tail_type;
if (pst_buf[0].data_type == DMX_DATA_WHOLE) {
return DMX_DATA_WHOLE;
}
head_type = pst_buf[0].data_type;
tail_type = pst_buf[buff_size - 1].data_type;
if (head_type == DMX_DATA_HEAD) {
if (tail_type == DMX_DATA_TAIL) {
return DMX_DATA_WHOLE;
} else {
return DMX_DATA_HEAD;
}
} else {
if (tail_type == DMX_DATA_TAIL) {
return DMX_DATA_TAIL;
} else {
return DMX_DATA_BODY;
}
}
}
static td_u32 dmx_play_copy_pes_together(td_u8 *pu8_dst, td_u32 dst_len, const dmx_buffer *pst_buf, td_u32 buf_num)
{
td_s32 ret;
td_u32 copyed_len = 0;
td_u32 i;
for (i = 0; i < buf_num; i++) {
if (dst_len - copyed_len < pst_buf[i].length) {
soc_log_err("dst_len or copyed_len is invalid!\n");
continue;
}
ret = memcpy_s(pu8_dst + copyed_len, dst_len - copyed_len, pst_buf[i].data, pst_buf[i].length);
if (ret != EOK) {
soc_log_err("memcpy_s failure ret: %d\n", ret);
return copyed_len;
}
copyed_len += pst_buf[i].length;
}
return copyed_len;
}
static td_s32 dmx_play_release_v1r6_pes_data(td_handle handle, td_u32 rel_num, const dmx_buffer *buf)
{
td_s32 ret;
dmx_play_fct_release_buf_info info = {
.handle = handle,
.rel_num = rel_num,
};
info.play_fct_buf = (dmx_buffer *)buf;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_RELEASEBUF, &info);
return ret;
}
static td_s32 dmx_play_acquire_v1r6_pes_data(td_handle handle, td_u32 *acqed_num, dmx_buffer *pst_buf,
const dmx_buffer *tmp_buf, td_u32 tmp_buf_num)
{
td_u32 i;
td_s32 pes_type, ret;
td_u32 pes_len;
td_u32 malloc_len = 0;
td_u8 *pu8_pes_mem = TD_NULL;
if (*acqed_num > 16) { /* 16 is acquire package number */
soc_log_err("param.acquired_num(%u) > 16, error!\n", *acqed_num);
return TD_FAILURE;
}
pes_type = dmx_play_check_pes_user_msg(tmp_buf, *acqed_num);
for (i = 0; i < *acqed_num; i++) {
malloc_len += tmp_buf[i].length;
}
pu8_pes_mem = (td_u8 *)malloc(malloc_len);
if (pu8_pes_mem == TD_NULL) {
soc_log_err("pes mem malloc failed!\n");
return TD_FAILURE;
}
pes_len = dmx_play_copy_pes_together(pu8_pes_mem, malloc_len, tmp_buf, *acqed_num);
/* free kernle buffer after copying */
ret = dmx_play_release_v1r6_pes_data(handle, *acqed_num, tmp_buf);
if (ret == TD_SUCCESS) {
pst_buf[0].data = pu8_pes_mem;
pst_buf[0].data_type = (dmx_data_type)pes_type;
pst_buf[0].length = pes_len;
*acqed_num = 1;
} else {
soc_log_err("release pes data failed! ret = 0x%x, acqed_num: %u\n", ret, *acqed_num);
free(pu8_pes_mem);
pu8_pes_mem = TD_NULL;
}
TD_UNUSED(tmp_buf_num);
return ret;
}
/*
* ts/sec/pes:
* return any data available, up to the AcqNum, if TimeOut is 0.
* return request data, if TimeOut is not 0 and not expired .
* return any data available, if TimeOut is not 0 and expired.
* avpes:
* return any data available, up to the AcqNum, if TimeOut is 0.
* return any data after data available immediately, if TimeOut is not 0 and not expired .
* return any data available, if TimeOut is not 0 and expired.
*/
td_s32 ext_mpi_dmx_play_acquire_buf(td_handle handle, td_u32 acq_num, td_u32 *acqed_num, dmx_buffer *buf,
td_u32 time_out)
{
td_s32 ret;
td_bool is_v1r6_pes_chan = TD_FALSE;
const td_u32 pes_default_num = 0x8; /* 8: max pes block num for v1r6 chip */
dmx_buffer pes_default_buf[0x8] = {{0}}; /* 8: max pes block num for v1r6 chip */
dmx_play_fct_acquire_buf_info info = {
.handle = handle,
.acq_num = acq_num,
.time_out = time_out,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (buf == TD_NULL || acqed_num == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = dmx_play_is_v1r6_pes_chan(handle, &is_v1r6_pes_chan);
if (ret != TD_SUCCESS) {
return ret;
}
info.acq_num = (is_v1r6_pes_chan == TD_TRUE) ? pes_default_num : acq_num;
info.play_fct_buf = (is_v1r6_pes_chan == TD_TRUE) ? pes_default_buf : buf;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_ACQUIREBUF, &info);
if (ret == TD_SUCCESS) {
if (is_v1r6_pes_chan == TD_TRUE) {
ret = dmx_play_acquire_v1r6_pes_data(handle, &info.acqed_num, buf, pes_default_buf, pes_default_num);
if (ret != TD_SUCCESS) {
soc_log_err("copy pes data together failed. ret = 0x%x\n", ret);
return ret;
}
}
*acqed_num = info.acqed_num;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_release_buf(td_handle handle, td_u32 rel_num, const dmx_buffer *buf)
{
td_s32 ret;
td_bool is_v1r6_pes_chan = TD_FALSE;
dmx_play_fct_release_buf_info info = {
.handle = handle,
.rel_num = rel_num,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (buf == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = dmx_play_is_v1r6_pes_chan(handle, &is_v1r6_pes_chan);
if (ret != TD_SUCCESS) {
return ret;
}
if (is_v1r6_pes_chan == TD_TRUE) {
if (buf[0].data != TD_NULL) {
free(buf[0].data);
}
return TD_SUCCESS;
}
info.play_fct_buf = (dmx_buffer *)buf;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_RELEASEBUF, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_reset_buf(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_RESETBUF, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_start_idx(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_STARTINDEX, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_recv_idx(td_handle handle, td_u32 req_num, td_u32 *reqed_num, dmx_index_data *index,
td_u32 time_out)
{
td_s32 ret;
dmx_play_index_info info = {
.handle = handle,
.req_num = req_num,
.time_out = time_out,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if ((index == TD_NULL) || (reqed_num == TD_NULL)) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.index_data = index;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_RECVINDEX, &info);
if (ret == TD_SUCCESS) {
*reqed_num = info.reqed_num;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_play_stop_idx(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_STOPINDEX, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_close(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_CLOSE, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_destroy(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
/* to stop callback thread */
ret = ext_mpi_dmx_play_unregister_callback(handle);
if (ret != TD_SUCCESS) {
soc_log_err("ext_mpi_dmx_play_unregister_callback failed, ret(%#x).\n", ret);
goto out;
}
ret = dmx_unmap(handle, DMX_IOCTL_PLAYFCT_PREMMAP);
if (ret != TD_SUCCESS) {
soc_log_err("unmap mem failed, ret(%d).\n", ret);
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_DESTROY, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_play_attach_ssm(td_handle handle, td_handle ssm)
{
td_s32 ret;
dmx_play_get_buf_handle handle_info = {0};
ext_ssm_buffer_attach_info attach_info = {0};
td_u64 sec_info_addr;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
handle_info.handle = handle;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_GET_BUFHANDLE, &handle_info);
if (ret != TD_SUCCESS) {
soc_log_err("get play fct %x buf handle failed,ssm %x ret %x.\n", handle, ssm, ret);
goto out0;
}
attach_info.dma_buf_handle = handle_info.buf_handle;
attach_info.module_handle = handle;
attach_info.session_handle = ssm;
if (handle_info.type == DMX_PLAY_TYPE_AUD) {
attach_info.buf_id = EXT_SSM_BUFFER_ID_DMX_AUD_ES_BUF;
} else if (handle_info.type == DMX_PLAY_TYPE_VID) {
attach_info.buf_id = EXT_SSM_BUFFER_ID_DMX_VID_ES_BUF;
} else {
attach_info.buf_id = EXT_SSM_BUFFER_ID_INTERNAL_BUF_DMX;
}
ret = ext_mpi_ssm_attach_buffer(&attach_info, &sec_info_addr);
if (ret != TD_SUCCESS) {
soc_log_err("play fct %x attach buffer failed, buffer handle %x, buffer_id %u, ret %x.\n",
handle, attach_info.dma_buf_handle, attach_info.buf_id, ret);
}
out0:
return ret;
}
static td_s32 mpi_dmx_rec_check_attrs(const dmx_rec_attrs *attrs)
{
td_s32 ret = SOC_ERR_DMX_INVALID_PARA;
if ((attrs->rec_buf_size < DMX_REC_MIN_BUF_SIZE) || (attrs->rec_buf_size > DMX_REC_MAX_BUF_SIZE)) {
soc_log_err("invalid rec buffer size:0x%x\n", attrs->rec_buf_size);
goto out;
}
if (attrs->rec_type >= DMX_REC_TYPE_MAX) {
soc_log_err("invalid rec type:0x%x\n", attrs->rec_type);
goto out;
}
if (attrs->rec_type == DMX_REC_TYPE_SELECT_PID) {
if (attrs->index_type >= DMX_REC_INDEX_TYPE_MAX) {
soc_log_err("invalid rec index type:0x%x\n", attrs->index_type);
goto out;
}
if (((attrs->index_type == DMX_REC_INDEX_TYPE_VIDEO || attrs->index_type == DMX_REC_INDEX_TYPE_AUDIO)) &&
(attrs->index_src_pid >= DMX_INVALID_PID)) {
soc_log_err("invalid rec pid:0x%x\n", attrs->index_src_pid);
goto out;
}
if (attrs->index_type == DMX_REC_INDEX_TYPE_VIDEO && attrs->vcodec_type >= DMX_VCODEC_TYPE_MAX) {
soc_log_err("invalid rec vcodec_type:0x%x\n", attrs->index_src_pid);
goto out;
}
}
if (attrs->ts_packet_type >= DMX_TS_PACKET_MAX) {
soc_log_err("invalid rec ts_packet_type:0x%x\n", attrs->ts_packet_type);
goto out;
}
if (attrs->secure_mode >= DMX_SECURE_MAX) {
soc_log_err("invalid rec secure_mode:0x%x\n", attrs->secure_mode);
goto out;
}
return TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_get_default_attrs(dmx_rec_attrs *attrs)
{
td_s32 ret;
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = memset_s(attrs, sizeof(dmx_rec_attrs), 0, sizeof(dmx_rec_attrs));
if (ret != EOK) {
soc_log_err("call memset_s failed. ret = 0x%x\n", ret);
return ret;
}
attrs->descramed = TD_TRUE;
attrs->index_type = DMX_REC_INDEX_TYPE_NONE;
attrs->rec_buf_size = DMX_DEFAULT_RECFCT_SIZE;
attrs->rec_type = DMX_REC_TYPE_ALL_PID;
attrs->secure_mode = DMX_SECURE_NONE;
attrs->index_src_pid = DMX_INVALID_PID;
attrs->vcodec_type = DMX_VCODEC_TYPE_MPEG2;
ret = TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_create(const dmx_rec_attrs *attrs, td_handle *handle)
{
td_s32 ret;
dmx_create_rec_fct_info info;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attrs == TD_NULL || handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out0;
}
ret = mpi_dmx_rec_check_attrs(attrs);
if (ret != TD_SUCCESS) {
soc_log_err("invalid attrs.\n");
goto out0;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_CREATE, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PLAYFCT_CREATE failed, ret[0x%x].\n", ret);
goto out0;
}
if (attrs->secure_mode != DMX_SECURE_TEE) {
ret = dmx_mmap(info.handle, DMX_IOCTL_RECFCT_PREMMAP, DMX_IOCTL_RECFCT_PSTMMAP);
if (ret != TD_SUCCESS) {
soc_log_err("dmx_mmap failed, ret[0x%x].\n", ret);
goto out1;
}
}
*handle = info.handle;
return TD_SUCCESS;
out1:
ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_DESTROY, &info.handle);
out0:
return ret;
}
td_s32 ext_mpi_dmx_rec_open(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_OPEN, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_get_attrs(td_handle handle, dmx_rec_attrs *attrs)
{
td_s32 ret;
dmx_get_rec_fct_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_GETATTRS, &info);
if (ret == TD_SUCCESS) {
*attrs = info.attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_set_attrs(td_handle handle, const dmx_rec_attrs *attrs)
{
td_s32 ret;
dmx_set_rec_fct_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_SETATTRS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_set_eos_flag(td_handle rec_chn, td_bool eos_flag)
{
td_s32 ret;
dmx_rec_set_eos_info info = {
.handle = rec_chn,
.eos_flag = eos_flag,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_SETEOS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_get_status(td_handle handle, dmx_rec_status *status)
{
td_s32 ret;
dmx_get_rec_fct_status_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (status == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_GETSTATUS, &info);
if (ret == TD_SUCCESS) {
*status = info.status;
}
out:
return ret;
}
/* support ch_handle point to a band, that is all ts record. */
td_s32 ext_mpi_dmx_rec_add_ch(td_handle handle, td_handle ch_handle)
{
td_s32 ret;
dmx_rec_fct_add_del_ch_info info = {
.handle = handle,
.ch_handle = ch_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_ADDCH, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_del_ch(td_handle handle, td_handle ch_handle)
{
td_s32 ret;
dmx_rec_fct_add_del_ch_info info = {
.handle = handle,
.ch_handle = ch_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_DELCH, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_del_all_ch(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_DELALLCH, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_acquire_buf(td_handle handle, td_u32 req_len, dmx_buffer *buf, td_u32 time_out)
{
td_s32 ret;
dmx_rec_fct_acquire_buf_info info = {
.handle = handle,
.req_len = req_len,
.time_out = time_out,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (buf == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.rec_fct_buf = buf;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_ACQUIREBUF, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_release_buf(td_handle handle, const dmx_buffer *buf)
{
td_s32 ret;
dmx_rec_fct_release_buf_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (buf == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.rec_fct_buf = (dmx_buffer *)buf;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_RELEASEBUF, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_recv_idx(td_handle handle, td_u32 req_num, td_u32 *reqed_num, dmx_index_data *index,
td_u32 time_out)
{
td_s32 ret;
dmx_rec_index_info info = {
.handle = handle,
.req_num = req_num,
.time_out = time_out,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if ((index == TD_NULL) || (reqed_num == TD_NULL)) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.index_data = index;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_RECVINDEX, &info);
if (ret == TD_SUCCESS) {
*reqed_num = info.reqed_num;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_acquire_rec_data_and_index(td_handle handle, dmx_rec_data_index *rec_data_index)
{
td_s32 ret;
ret = check_handle(handle);
if (ret != TD_SUCCESS) {
soc_log_err("invalid parameter.\n");
return SOC_ERR_DMX_INVALID_PARA;
}
TD_UNUSED(rec_data_index);
return ret;
}
td_s32 ext_mpi_dmx_release_rec_data_and_index(td_handle handle, const dmx_rec_data_index *rec_data_index)
{
td_s32 ret;
ret = check_handle(handle);
if (ret != TD_SUCCESS) {
soc_log_err("invalid parameter.\n");
return SOC_ERR_DMX_INVALID_PARA;
}
TD_UNUSED(rec_data_index);
return ret;
}
td_s32 ext_mpi_dmx_rec_peek_idx_and_buf(td_handle handle, td_u32 *idx_num, td_u32 *data_len, td_u32 time_out)
{
td_s32 ret;
dmx_rec_peek_idx_buf_info info = {
.handle = handle,
.time_out = time_out,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (idx_num == TD_NULL || data_len == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_PEEK_IDX_BUF, &info);
if (ret == TD_SUCCESS) {
*idx_num = info.index_num;
*data_len = info.rec_data_len;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_close(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_CLOSE, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_destroy(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = dmx_unmap(handle, DMX_IOCTL_RECFCT_PREMMAP);
if (ret != TD_SUCCESS) {
soc_log_err("unmap mem failed, ret(%d).\n", ret);
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_DESTROY, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rec_attach_ssm(td_handle handle, td_handle ssm, dmx_buffer_attach_type attach_type)
{
td_s32 ret;
dmx_rec_get_buf_handle handle_info = {0};
ext_ssm_buffer_attach_info attach_info = {0};
td_u64 sec_info_addr;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out0;
}
if (attach_type >= EXT_DMX_BUFFER_ATTACH_MAX) {
soc_log_err("Invalid attach type %u.\n", attach_type);
return SOC_ERR_DMX_INVALID_PARA;
}
handle_info.handle = handle;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RECFCT_GETBUFHANDLE, &handle_info);
if (ret != TD_SUCCESS) {
soc_log_err("get rec fct %x buf handle failed,ssm %x attach type %u ret %x.\n", handle, ssm, attach_type, ret);
goto out0;
}
attach_info.dma_buf_handle = handle_info.buf_handle;
attach_info.buf_id = EXT_SSM_BUFFER_ID_PVR_RECORD_TS_BUF;
attach_info.module_handle = handle;
attach_info.session_handle = ssm;
ret = ext_mpi_ssm_attach_buffer(&attach_info, &sec_info_addr);
if (ret != TD_SUCCESS) {
soc_log_err("rec fct %x attach buffer failed, buffer handle %x, buffer id %u, ret %x.\n", handle,
attach_info.dma_buf_handle, attach_info.buf_id, ret);
goto out0;
}
out0:
return ret;
}
td_s32 ext_mpi_dmx_dsc_get_default_attrs(dmx_dsc_attrs *attrs)
{
td_s32 ret;
if (attrs == TD_NULL) {
soc_log_err("invalid parameter, null ptr\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
attrs->ca_type = DMX_CA_NORMAL;
attrs->entropy_reduction = DMX_CA_ENTROPY_CLOSE;
attrs->alg = DMX_DESCRAMBLER_TYPE_CSA2;
ret = TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_create(const dmx_dsc_attrs *attrs, td_handle *handle)
{
td_s32 ret;
dmx_create_dsc_fct_info info;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL || handle == TD_NULL) {
soc_log_err("invalid parameter, null ptr\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_CREATE, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_DSCFCT_CREATE failed, ret[0x%x].\n", ret);
goto out;
}
*handle = info.handle;
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_get_attrs(td_handle handle, dmx_dsc_attrs *attrs)
{
td_s32 ret;
dmx_get_dsc_fct_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter, null ptr\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_GETATTRS, &info);
if (ret == TD_SUCCESS) {
*attrs = info.attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_set_attrs(td_handle handle, const dmx_dsc_attrs *attrs)
{
td_s32 ret;
dmx_set_dsc_fct_attr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter, null ptr\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_SETATTRS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_attach(td_handle handle, td_handle ch_handle)
{
td_s32 ret;
dmx_dsc_fct_attach_info info = {
.handle = handle,
.target_handle = ch_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_ATTACH, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_detach(td_handle handle, td_handle ch_handle)
{
td_s32 ret;
dmx_dsc_fct_detach_info info = {
.handle = handle,
.target_handle = ch_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_DETACH, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_attach_keyslot(td_handle handle, td_handle ks_handle)
{
td_s32 ret;
dmx_dsc_fct_attach_info info = {
.handle = handle,
.target_handle = ks_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_ATTACH_KEYSLOT, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_detach_keyslot(td_handle handle)
{
td_s32 ret;
dmx_dsc_fct_detach_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_DETACH_KEYSLOT, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_get_keyslot_handle(td_handle handle, td_handle *ks_handle)
{
td_s32 ret;
dmx_dsc_fct_get_ks_handle_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (ks_handle == TD_NULL) {
soc_log_err("invalid parameter,null ptr\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_GET_KS_HANDLE, &info);
if (ret == TD_SUCCESS) {
*ks_handle = info.ks_handle;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_set_even_iv(td_handle handle, const td_u8 *even_iv, td_u32 len)
{
td_s32 ret;
dmx_dsc_fct_set_key_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (even_iv == TD_NULL) {
soc_log_err("invalid parameter, null ptr.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
if (len < DMX_MIN_KEY_LEN || len > DMX_MAX_KEY_LEN) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.len = len;
ret = memset_s(info.key, sizeof(info.key), 0x0, sizeof(info.key));
if (ret != EOK) {
soc_log_err("call memset_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = memcpy_s(info.key, sizeof(info.key), even_iv, len);
if (ret != EOK) {
soc_log_err("call memcpy_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_SETEVENIV, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_set_odd_iv(td_handle handle, const td_u8 *odd_iv, td_u32 len)
{
td_s32 ret;
dmx_dsc_fct_set_key_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (odd_iv == TD_NULL) {
soc_log_err("invalid parameter, null ptr.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
if (len < DMX_MIN_KEY_LEN || len > DMX_MAX_KEY_LEN) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.len = len;
ret = memset_s(info.key, sizeof(info.key), 0x0, sizeof(info.key));
if (ret != EOK) {
soc_log_err("call memset_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = memcpy_s(info.key, sizeof(info.key), odd_iv, len);
if (ret != EOK) {
soc_log_err("call memcpy_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_SETODDIV, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_set_even_key(td_handle handle, const td_u8 *even_key, td_u32 len)
{
td_s32 ret;
dmx_dsc_fct_set_key_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (even_key == TD_NULL) {
soc_log_err("invalid parameter, null ptr.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
if (len < DMX_MIN_KEY_LEN || len > DMX_MAX_KEY_LEN) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.len = len;
ret = memset_s(info.key, sizeof(info.key), 0x0, sizeof(info.key));
if (ret != EOK) {
soc_log_err("call memset_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = memcpy_s(info.key, sizeof(info.key), even_key, len);
if (ret != EOK) {
soc_log_err("call memcpy_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_SETEVENKEY, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_set_odd_key(td_handle handle, const td_u8 *odd_key, td_u32 len)
{
td_s32 ret;
dmx_dsc_fct_set_key_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (odd_key == TD_NULL) {
soc_log_err("invalid parameter, null ptr.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
if (len < DMX_MIN_KEY_LEN || len > DMX_MAX_KEY_LEN) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.len = len;
ret = memset_s(info.key, sizeof(info.key), 0x0, sizeof(info.key));
if (ret != EOK) {
soc_log_err("call memset_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = memcpy_s(info.key, sizeof(info.key), odd_key, len);
if (ret != EOK) {
soc_log_err("call memcpy_s failed. ret = 0x%x\n", ret);
return ret;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_SETODDKEY, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_set_sys_key(td_handle handle, const td_u8 *sys_key, td_u32 len)
{
td_s32 ret;
dmx_dsc_fct_set_sys_key_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
return ret;
}
if (sys_key == TD_NULL) {
soc_log_err("invalid parameter, null ptr.\n");
return SOC_ERR_DMX_NULL_PTR;
}
if (len != DMX_SYS_KEY_LEN) {
soc_log_err("invalid parameter.\n");
return SOC_ERR_DMX_INVALID_PARA;
}
info.len = len;
ret = memset_s(info.key, sizeof(info.key), 0x0, sizeof(info.key));
if (ret != TD_SUCCESS) {
soc_log_err("memset_s failed!\n");
return ret;
}
ret = memcpy_s(info.key, sizeof(info.key), sys_key, len);
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed!\n");
return ret;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_SETSYSKEY, &info);
return ret;
}
td_s32 ext_mpi_dmx_dsc_destroy(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_DESTROY, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_get_dsc_key_handle(td_handle pid_ch_handle, td_handle *dsc_handle)
{
td_s32 ret;
dmx_dsc_fct_get_key_handle_info info = {
.pid_ch_handle = pid_ch_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (dsc_handle == TD_NULL) {
soc_log_err("invalid parameter, null ptr\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_GET_KEY_HANDLE, &info);
if (ret == TD_SUCCESS) {
*dsc_handle = info.dsc_handle;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_dsc_get_free_dsc_key_cnt(td_u32 *free_cnt)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (free_cnt == TD_NULL) {
soc_log_err("invalid parameter, null ptr.\n");
ret = SOC_ERR_DMX_NULL_PTR;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_DSCFCT_GET_FREE_CNT, free_cnt);
out:
return ret;
}
td_s32 ext_mpi_dmx_pcr_create(td_handle band_handle, td_u32 pid, td_handle *handle)
{
td_s32 ret;
dmx_create_pcr_fct_info info = {
.band_handle = band_handle,
.pid = pid,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PCRFCT_CREATE, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PCRFCT_CREATE failed, ret[0x%x].\n", ret);
goto out;
}
*handle = info.handle;
out:
return ret;
}
td_s32 ext_mpi_dmx_pcr_attach_sync(td_handle handle, td_handle sync_handle)
{
td_s32 ret;
dmx_pcr_fct_attach_info info = {
.handle = handle,
.sync_handle = sync_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PCRFCT_ATTACH, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PCRFCT_ATTACH failed, ret[0x%x].\n", ret);
goto out;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_pcr_detach_sync(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PCRFCT_DETACH, &handle);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PCRFCT_DETACH failed, ret[0x%x].\n", ret);
goto out;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_pcr_get_pcr_scr(td_handle handle, td_u64 *pcr_ms, td_u64 *scr_ms)
{
td_s32 ret;
dmx_pcr_fct_get_pcr_scr_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (pcr_ms == TD_NULL || scr_ms == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PCRFCT_GETPCRSCR, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PCRFCT_GETPCRSCR failed, ret[0x%x].\n", ret);
goto out;
}
*pcr_ms = info.pcr_ms;
*scr_ms = info.scr_ms;
out:
return ret;
}
td_s32 ext_mpi_dmx_pcr_get_status(td_handle handle, dmx_pcr_status *status)
{
td_s32 ret;
dmx_get_pcr_fct_status_info info = {
.handle = handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (status == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PCRFCT_GETSTATUS, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_PCRFCT_GETSTATUS failed, ret[0x%x].\n", ret);
goto out;
}
*status = info.status;
out:
return ret;
}
td_s32 ext_mpi_dmx_pcr_destroy(td_handle handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PCRFCT_DESTROY, &handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_get_default_attrs(dmx_rmx_attrs *attrs)
{
td_s32 ret;
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
attrs->out_port_id = DMX_RMX_PORT_0;
ret = TD_SUCCESS;
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_create(const dmx_rmx_attrs *attrs, td_handle *rmx_handle)
{
td_s32 ret;
dmx_create_rmx_fct_info info;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL || rmx_handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_CREATE, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_RMXFCT_CREATE failed, ret[0x%x].\n", ret);
goto out;
}
*rmx_handle = info.rmx_handle;
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_open(td_handle rmx_handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_OPEN, &rmx_handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_get_attrs(td_handle rmx_handle, dmx_rmx_attrs *attrs)
{
td_s32 ret;
dmx_get_rmx_fct_attr_info info = {
.rmx_handle = rmx_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_GETATTRS, &info);
if (ret == TD_SUCCESS) {
*attrs = info.attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_set_attrs(td_handle rmx_handle, const dmx_rmx_attrs *attrs)
{
td_s32 ret;
dmx_set_rmx_fct_attr_info info = {
.rmx_handle = rmx_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.attrs = *attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_SETATTRS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_get_status(td_handle rmx_handle, dmx_rmx_status *status)
{
td_s32 ret;
dmx_get_rmx_fct_status_info info = {
.rmx_handle = rmx_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (status == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_GETSTATUS, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_RMXFCT_GETSTATUS failed, ret[0x%x].\n", ret);
goto out;
}
*status = info.status;
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_get_pump_default_attrs(dmx_rmx_pump_attrs *pump_attrs)
{
td_s32 ret;
if (pump_attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
pump_attrs->pump_type = DMX_RMX_PUMP_TYPE_PID;
pump_attrs->in_port_id = DMX_TSI_PORT_0;
pump_attrs->pid = 0;
pump_attrs->remap_pid = 0;
ret = TD_SUCCESS;
out:
return ret;
}
static td_s32 mpi_dmx_rmx_check_pump_attrs(const dmx_rmx_pump_attrs *attrs)
{
if (attrs->pump_type >= EXT_MPI_RMX_PUMP_TYPE_MAX) {
soc_log_err("invalid pump type(%u).\n", attrs->pump_type);
return SOC_ERR_DMX_INVALID_PARA;
}
if (!(attrs->in_port_id >= DMX_IF_PORT_0 && attrs->in_port_id < DMX_IF_PORT_MAX) &&
!(attrs->in_port_id >= DMX_TSI_PORT_0 && attrs->in_port_id < DMX_TSI_PORT_MAX) &&
!(attrs->in_port_id >= DMX_RAM_PORT_0 && attrs->in_port_id < DMX_RAM_PORT_MAX)) {
soc_log_err("invalid port id(%d).\n", attrs->in_port_id);
return SOC_ERR_DMX_INVALID_PARA;
}
if (attrs->pump_type == DMX_RMX_PUMP_TYPE_PID && attrs->pid >= DMX_INVALID_PID) {
soc_log_err("invalid pid(%d).\n", attrs->pid);
return SOC_ERR_DMX_INVALID_PARA;
}
if (attrs->pump_type == DMX_RMX_PUMP_TYPE_REMAP_PID &&
(attrs->pid >= DMX_INVALID_PID || attrs->remap_pid >= DMX_INVALID_PID)) {
soc_log_err("invalid pid(%d) or remap pid(%d).\n", attrs->pid, attrs->remap_pid);
return SOC_ERR_DMX_INVALID_PARA;
}
return TD_SUCCESS;
}
td_s32 ext_mpi_dmx_rmx_add_pump(td_handle rmx_handle, const dmx_rmx_pump_attrs *pump_attrs, td_handle *rmx_pump_handle)
{
td_s32 ret;
dmx_rmx_fct_add_pump_info info = {
.rmx_handle = rmx_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (pump_attrs == TD_NULL || rmx_pump_handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = mpi_dmx_rmx_check_pump_attrs(pump_attrs);
if (ret != TD_SUCCESS) {
soc_log_err("invalid pump_attrs.\n");
goto out;
}
info.pump_attrs = *pump_attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_ADDPUMP, &info);
if (ret != TD_SUCCESS) {
soc_log_err("DMX_IOCTL_RMXFCT_ADDPUMP failed, ret[0x%x].\n", ret);
goto out;
}
*rmx_pump_handle = info.rmx_pump_handle;
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_del_pump(td_handle rmx_pump_handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_DELPUMP, &rmx_pump_handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_del_all_pump(td_handle rmx_handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_DELALLPUMP, &rmx_handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_get_pump_attrs(td_handle rmx_pump_handle, dmx_rmx_pump_attrs *pump_attrs)
{
td_s32 ret;
dmx_get_rmx_pump_attr_info info = {
.rmx_pump_handle = rmx_pump_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (pump_attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_GETPUMPATTRS, &info);
if (ret == TD_SUCCESS) {
*pump_attrs = info.pump_attrs;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_set_pump_attrs(td_handle rmx_pump_handle, const dmx_rmx_pump_attrs *pump_attrs)
{
td_s32 ret;
dmx_set_rmx_pump_attr_info info = {
.rmx_pump_handle = rmx_pump_handle,
};
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (pump_attrs == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
info.pump_attrs = *pump_attrs;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_SETPUMPATTRS, &info);
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_close(td_handle rmx_handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_CLOSE, &rmx_handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_rmx_destroy(td_handle rmx_handle)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_RMXFCT_DESTROY, &rmx_handle);
out:
return ret;
}
td_s32 ext_mpi_dmx_invoke(dmx_invoke_type cmd, const td_void *para)
{
td_s32 ret;
ret = dev_opened();
if (ret != TD_SUCCESS) {
goto out;
}
if (para == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
if (cmd == EXT_DMX_INVOKE_TYPE_CHAN_CC_REPEAT_SET) {
dmx_set_chan_cc_repeat_info info = *(dmx_set_chan_cc_repeat_info *)para;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_CC_REPEAT_SET, &info);
} else if (cmd == EXT_DMX_INVOKE_TYPE_PUSI_SET) {
dmx_pusi_set_info info = *(dmx_pusi_set_info *)para;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_PLAYFCT_PUSI_SET, &info);
} else if (cmd == EXT_DMX_INVOKE_TYPE_TEI_SET) {
dmx_tei_set_info info = *(dmx_tei_set_info *)para;
ret = ioctl(g_dmx_dev_fd, DMX_IOCTL_BAND_TEI_SET, &info);
} else if (cmd == EXT_DMX_INVOKE_TYPE_TSI_ATTACH_TSO) {
ret = SOC_ERR_DMX_NOT_SUPPORT;
} else {
soc_log_err("unknown invoke cmd.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
}
out:
return ret;
}
td_s32 ext_mpi_dmx_get_pid_lock(td_void)
{
td_s32 ret;
ret = pthread_mutex_lock(&g_pid_lock);
if (ret != 0) {
soc_log_err("pthread_mutex_lock failed.\n");
return TD_FAILURE;
}
return TD_SUCCESS;
}
td_void ext_mpi_dmx_release_pid_lock(td_void)
{
pthread_mutex_unlock(&g_pid_lock);
}
td_s32 ext_mpi_dmx_detach_and_dec_pidch(td_handle play_chan, td_handle pidch_handle)
{
td_s32 ret;
ret = ext_mpi_dmx_get_pid_lock();
if (ret != 0) {
soc_log_err("pthread_mutex_lock failed.\n");
goto out;
}
ret = ext_mpi_dmx_play_detach_pid_ch(play_chan);
if (ret != TD_SUCCESS) {
soc_log_err("detach pid ch failed.\n");
goto out_pid_unlock;
}
if (pidch_handle != TD_INVALID_HANDLE) {
ret = ext_mpi_dmx_pid_ch_ref_dec(pidch_handle);
if (ret != TD_SUCCESS) {
soc_log_err("pid ch ref dec failed, ret(0x%x).\n", ret);
goto out_pid_unlock;
}
}
ext_mpi_dmx_release_pid_lock();
return TD_SUCCESS;
out_pid_unlock:
ext_mpi_dmx_release_pid_lock();
out:
return ret;
}
td_s32 ext_mpi_dmx_inc_and_attach_pidch(td_handle band_handle, td_u32 pid, td_handle play_chan, td_handle *pidch_handle)
{
td_s32 ret;
td_handle local_pidch_handle;
if (pidch_handle == TD_NULL) {
soc_log_err("invalid parameter.\n");
ret = SOC_ERR_DMX_INVALID_PARA;
goto out;
}
ret = ext_mpi_dmx_get_pid_lock();
if (ret != 0) {
soc_log_err("pthread_mutex_lock failed.\n");
goto out;
}
ret = ext_mpi_dmx_pid_ch_ref_inc(band_handle, pid, &local_pidch_handle);
if (ret != TD_SUCCESS) {
soc_log_err("pid ch ref inc failed, ret(0x%x), handle(%u), pid(%u).\n", ret, band_handle, pid);
goto out_pid_unlock;
}
ret = ext_mpi_dmx_play_attach_pid_ch(play_chan, local_pidch_handle);
if (ret != TD_SUCCESS) {
soc_log_err("attach pid ch failed, ret(0x%x).\n", ret);
goto dec;
}
*pidch_handle = local_pidch_handle;
ext_mpi_dmx_release_pid_lock();
return TD_SUCCESS;
dec:
if (ext_mpi_dmx_pid_ch_ref_dec(local_pidch_handle) != TD_SUCCESS) {
soc_log_err("pid ch ref dec failed.\n");
}
out_pid_unlock:
ext_mpi_dmx_release_pid_lock();
out:
return ret;
}