decoding support

This commit is contained in:
internal
2024-02-05 10:27:55 +01:00
parent 1124f00b34
commit a1c604f212
6 changed files with 420 additions and 35 deletions

View File

@@ -7,6 +7,7 @@
#include <linux/dvb/frontend.h>
#include <linux/dvb/video.h>
#include <linux/dvb/net.h>
#include <linux/dvb/ca.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -252,6 +253,24 @@ static int handle_pmts(struct dddvb_ca *ca)
return 0;
}
void dump(FILE *fp, uint8_t *b, int l)
{
int i, j;
for (j = 0; j < l; j += 16, b += 16) {
for (i = 0; i < 16; i++)
if (i + j < l)
fprintf(fp, "%02x ", b[i]);
else
fprintf(fp, " ");
fprintf(fp, " | ");
for (i = 0; i < 16; i++)
if (i + j < l)
fprintf(fp, "%c", (b[i] > 31 && b[i] < 127) ? b[i] : '.');
fprintf(fp, "\n");
}
}
static int set_pmts(struct dddvb_ca *ca, uint8_t **pmts)
{
int listmgmt = CA_LIST_MANAGEMENT_ONLY;
@@ -273,10 +292,26 @@ static int set_pmts(struct dddvb_ca *ca, uint8_t **pmts)
len = ((sec[1] & 0x0f) << 8) | sec[2];
len += 3;
memcpy(sec, pmts[i], len);
//dump(stderr, sec, len);
section = section_codec(sec, len);
if (!section) {
dbgprintf(DEBUG_CA, "section_codec failed\n");;
continue;
}
section_ext = section_ext_decode(section, 0);
if (!section_ext) {
dbgprintf(DEBUG_CA, "section_ext_decode failed\n");;
continue;
}
pmt = mpeg_pmt_section_codec(section_ext);
//pmt = (struct mpeg_pmt_section *) section_ext;
if (!pmt) {
dbgprintf(DEBUG_CA, "mpeg_pmt_section_codec failed\n");;
continue;
}
dbgprintf(DEBUG_CA, "PMT = %p section=%p\n", pmt, section);
ca->ca_pmt_version[i] = section_ext->version_number;
if (ca->sentpmt) {
//return 0;
@@ -291,14 +326,16 @@ static int set_pmts(struct dddvb_ca *ca, uint8_t **pmts)
listmgmt = CA_LIST_MANAGEMENT_LAST;
}
}
dbgprintf(DEBUG_CA, "set ca_pmt\n");
//dump(stderr, (uint8_t *) pmt, len);
dbgprintf(DEBUG_CA, "format ca_pmt %p length %u\n", pmt, len);
if ((size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), ca->moveca, listmgmt,
CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
dbgprintf(DEBUG_CA, "Failed to format PMT\n");
return -1;
}
//dump(capmt, size);
dbgprintf(DEBUG_CA, "set ca_pmt\n");
if (en50221_app_ca_pmt(ca->stdcam->ca_resource, ca->stdcam->ca_session_number, capmt, size)) {
dbgprintf(DEBUG_CA, "Failed to send PMT\n");
return -1;
@@ -585,7 +622,7 @@ static int mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t snum,
static int init_ca_stack(struct dddvb_ca *ca)
{
{
ca->tl = en50221_tl_create(1, 16);
if (ca->tl == NULL) {
dbgprintf(DEBUG_CA, "Failed to create transport layer\n");
@@ -625,6 +662,19 @@ static int init_ca_stack(struct dddvb_ca *ca)
return 0;
}
void cam_reset(int fd)
{
ca_slot_info_t info;
info.num = 0;
if (ioctl(fd, CA_GET_SLOT_INFO, &info))
return;
if (info.flags & CA_CI_MODULE_READY)
return;
if (!(info.flags & CA_CI_MODULE_PRESENT))
return;
ioctl(fd, CA_RESET);
}
static int init_ca(struct dddvb *dd, int a, int f, int fd)
{
@@ -640,6 +690,8 @@ static int init_ca(struct dddvb *dd, int a, int f, int fd)
ca->nr = dd->dvbca_num + 1;
ca->fd = fd;
pthread_mutex_init(&ca->mutex, 0);
//cam_reset(fd);
init_ca_stack(ca);
@@ -671,7 +723,7 @@ int dddvb_ca_set_pmts(struct dddvb *dd, uint32_t nr, uint8_t **pmts)
{
struct dddvb_ca *ca = &dd->dvbca[nr];
dbgprintf(DEBUG_CA, "ca_set_pmt\n");
dbgprintf(DEBUG_CA, "ca%u.%u.%u:ca_set_pmt\n", ca->nr,ca->anum,ca->fnum);
return set_pmts(ca, pmts);
}

View File

@@ -71,7 +71,7 @@ LIBDDDVB_EXPORTED struct dddvb *dddvb_init(char *config, uint32_t flags)
struct dddvb *dd;
pthread_mutexattr_t mta;
dddvb_debug = flags;
dddvb_debug = flags & 0xff;
pthread_mutex_lock(&dddvb_mutex);
if (global_dd) {
@@ -90,9 +90,11 @@ LIBDDDVB_EXPORTED struct dddvb *dddvb_init(char *config, uint32_t flags)
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&dd->lock, &mta);
dd->get_ts = (flags & 0x100) ? 0 : 1;
dd->use_ca = (flags & 0x200) ? 0 : 1;
dddvb_dvb_init(dd);
global_dd = dd;
dd->get_ts = 1;
fail:
pthread_mutex_unlock(&dddvb_mutex);
return dd;

View File

@@ -158,7 +158,8 @@ struct dddvb {
unsigned int cam_proto;
unsigned int cam_port;
unsigned int get_ts:1;
unsigned int get_ts;
unsigned int use_ca;
};
int dddvb_dvb_init(struct dddvb *dd);

View File

@@ -605,6 +605,7 @@ int open_dmx(struct dddvb_fe *fe)
struct dmx_pes_filter_params pesFilterParams;
sprintf(fname, "/dev/dvb/adapter%u/demux%u", fe->anum, fe->fnum);
dbgprintf(DEBUG_DVB, "open %s\n", fname);
fe->dmx = open(fname, O_RDWR);
if (fe->dmx < 0)
@@ -690,7 +691,6 @@ void dddvb_fe_handle(struct dddvb_fe *fe)
uint32_t newtune, count = 0, max, nolock = 0;
int ret;
if (fe->dd->get_ts)
open_dmx(fe);
while (fe->state == 1) {
@@ -727,13 +727,14 @@ void dddvb_fe_handle(struct dddvb_fe *fe)
break;
count = 0;
get_stats(fe);
dbgprintf(DEBUG_DVB, "fe: nolock = %u, stat = %u\n", nolock, fe->stat);
if (fe->lock) {
max = 20;
nolock = 0;
} else {
max = 1;
nolock++;
if (nolock > 40)
if (nolock > 200 || fe->stat == FE_TIMEDOUT)
fe->tune = 1;
}
break;
@@ -799,7 +800,7 @@ static int dddvb_fe_init(struct dddvb *dd, int a, int f, int fd)
int r;
uint32_t i, ds;
if (dd->dvbca_num >= DDDVB_MAX_DVB_CA)
if (dd->dvbfe_num >= DDDVB_MAX_DVB_FE)
return -1;
fe = &dd->dvbfe[dd->dvbfe_num];
@@ -1034,7 +1035,8 @@ int dddvb_dvb_init(struct dddvb *dd)
if (dd->cam_port == 0)
dd->cam_port = 8888;
}
scan_dvbca(dd);
if (dd->use_ca)
scan_dvbca(dd);
}