summaryrefslogtreecommitdiff
authorGong Ke <ke.gong@amlogic.com>2018-01-10 09:21:18 (GMT)
committer Gong Ke <ke.gong@amlogic.com>2018-01-10 09:21:18 (GMT)
commit0e3343d7f936361567270e859c0edbbb4c8a5154 (patch)
tree8f70f569f5ecc2152a11b99b74980e204a3a8549
parenta29ba7e98846b2e771337b7dead9cba959fa5672 (diff)
downloaddvb-0e3343d7f936361567270e859c0edbbb4c8a5154.zip
dvb-0e3343d7f936361567270e859c0edbbb4c8a5154.tar.gz
dvb-0e3343d7f936361567270e859c0edbbb4c8a5154.tar.bz2
DTVCC: support scte [1/1]
PD# 157054 Change-Id: Ice1e8bb0d90f60612d26a5fc8ffb5cbb2934d212
Diffstat
-rw-r--r--am_adp/am_userdata/aml/aml.c146
-rwxr-xr-xlib32/libam_ver.so6
-rwxr-xr-xlib64/libam_ver.so4
-rwxr-xr-xlibam_ver.so5
4 files changed, 148 insertions, 13 deletions
diff --git a/am_adp/am_userdata/aml/aml.c b/am_adp/am_userdata/aml/aml.c
index 6735d91..56a6466 100644
--- a/am_adp/am_userdata/aml/aml.c
+++ b/am_adp/am_userdata/aml/aml.c
@@ -42,6 +42,7 @@
#define IS_DIRECTV(p) ((p[0] == 0xb5 && p[1] == 0x00 && p[2] == 0x2f))
#define IS_AVS(p) ((p[0] == 0x47) && (p[1] == 0x41) && (p[2] == 0x39) && (p[3] == 0x34))
#define IS_ATSC(p) ((p[0] == 0x47) && (p[1] == 0x41) && (p[2] == 0x39) && (p[3] == 0x34))
+#define IS_SCTE(p) ((p[0]==0x3) && (p[1]=0x81))
#define AMSTREAM_IOC_MAGIC 'S'
#define AMSTREAM_IOC_UD_LENGTH _IOR(AMSTREAM_IOC_MAGIC, 0x54, unsigned long)
@@ -57,7 +58,8 @@ typedef enum {
MPEG_CC_TYPE = 1,
H264_CC_TYPE = 2,
DIRECTV_CC_TYPE = 3,
- AVS_CC_TYPE = 4
+ AVS_CC_TYPE = 4,
+ SCTE_CC_TYPE = 5
} userdata_type;
@@ -104,6 +106,7 @@ typedef struct {
int cc_num;
userdata_type format;
int curr_poc;
+ int scte_enable;
} AM_UDDrvData;
@@ -159,6 +162,33 @@ static void aml_swap_data(uint8_t *user_data, int ud_size)
}
}
+static uint8_t scte20_char_map[256];
+
+static uint8_t
+scte20_get_char (uint8_t c)
+{
+ if (scte20_char_map[0] == 0) {
+ int i;
+
+ for (i = 0; i < 256; i ++) {
+ uint8_t v1, v2;
+ int b;
+
+ v1 = i;
+ v2 = 0;
+
+ for (b = 0; b < 8; b ++) {
+ if (v1 & (1 << b))
+ v2 |= (1 << (7 - b));
+ }
+
+ scte20_char_map[i] = v2;
+ }
+ }
+
+ return scte20_char_map[c];
+}
+
static userdata_type aml_check_userdata_format (uint8_t *buf, int len)
{
if (len < 8)
@@ -173,6 +203,9 @@ static userdata_type aml_check_userdata_format (uint8_t *buf, int len)
} else if (IS_AVS(buf)) {
AM_DEBUG(1,"CC format is avs_cc_type");
return AVS_CC_TYPE;
+ } else if (IS_SCTE(buf)) {
+ AM_DEBUG(1, "CC format is scte_cc_type");
+ return SCTE_CC_TYPE;
} else if (len >= (int)sizeof(aml_ud_header_t)) {
aml_ud_header_t *hdr = (aml_ud_header_t*)buf;
@@ -327,18 +360,117 @@ static void aml_mpeg_userdata_package(AM_USERDATA_Device_t *dev, int poc, int ty
aml_add_cc_data(dev, poc, type, p, len);
}
+static int aml_process_scte_userdata(AM_USERDATA_Device_t *dev, uint8_t *data, int len)
+{
+ int cc_count = 0, cnt, i;
+ int field_num;
+ uint8_t* cc_section;
+ uint8_t cc_data[64] = {0};
+ uint8_t* scte_head;
+ int head_posi = 0;
+ int prio, field, line, cc1, cc2, mark, size, ptype, ref;
+ int write_position, bits = 0, array_position = 0;
+ uint8_t *p;
+ int left = len;
+ int left_bits = (left << 3);
+ uint32_t v;
+ AM_UDDrvData *ud = dev->drv_data;
+ if (ud->scte_enable != 1)
+ return len;
+ v = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
+ ref = (v >> 16) & 0x3f;
+ ptype = (v >> 26) & 7;
+
+ if (ptype == I_TYPE)
+ aml_flush_cc_data(dev);
+
+ scte_head = data;
+ while (head_posi < len)
+ {
+ if (scte_head[head_posi] == 0x3 && scte_head[head_posi+1] == 0x81)
+ break;
+ head_posi += 8;
+ }
+
+ if ((len - head_posi) < 8)
+ return len;
+
+ p = &data[head_posi + 2];
+ cc_data[0] = 0x47;
+ cc_data[1] = 0x41;
+ cc_data[2] = 0x39;
+ cc_data[3] = 0x34;
+ cc_data[4] = 0x3;
+#define NST_BITS(v, b, l) (((v) >> (b)) & (0xff >> (8 - (l))))
+#define GET(n, b)\
+ do \
+ {\
+ int off, bs;\
+ if (bits + b > left_bits) goto error;\
+ off = bits >> 3;\
+ bs = bits & 7;\
+ if (8 - bs >= b) {\
+ n = NST_BITS(p[off], 8 - bs - b, b);\
+ } else {\
+ int n1, n2, b1 = 8 - bs, b2 = b- b1;\
+ n1 = NST_BITS(p[off], 0, b1);\
+ n2 = NST_BITS(p[off + 1], 8 - b + b1, b - b1);\
+ n = (n1 << b2) | n2;\
+ }\
+ bits += b;\
+ } while(0)
+
+ GET(cnt, 5);
+ array_position = 7;
+ for (i = 0; i < cnt; i ++) {
+ GET(prio, 2);
+ GET(field, 2);
+ GET(line, 5);
+ GET(cc1, 8);
+ GET(cc2, 8);
+ GET(mark, 1);
+
+ if (field == 1 && (line+10 == 21))
+ {
+ cc_data[array_position] = 4;
+ cc_data[array_position + 1] = scte20_get_char(cc1);
+ cc_data[array_position + 2] = scte20_get_char(cc2);
+ array_position += 3;
+ cc_count++;
+ }
+ else if (field == 2 && (line+273 == 274))
+ {
+ cc_data[array_position] = 4 | 1;
+ cc_data[array_position + 1] = scte20_get_char(cc1);
+ cc_data[array_position + 2] = scte20_get_char(cc2);
+ array_position += 3;
+ cc_count++;
+ }
+ }
+ cc_data[5] = 0x40 |cc_count;
+ size = 7 + cc_count*3;
+ if (cc_count > 0)
+ aml_add_cc_data(dev, ref, ptype, cc_data, size);
+ error:
+ return len;
+}
+
static int aml_process_mpeg_userdata(AM_USERDATA_Device_t *dev, uint8_t *data, int len)
{
AM_UDDrvData *ud = dev->drv_data;
uint8_t *pd = data;
int left = len;
int r = 0;
+ int i;
+ char display[1024];
+ int package_count = 0;
+ ud->scte_enable = 0;
while (left >= (int)sizeof(aml_ud_header_t)) {
aml_ud_header_t *hdr = (aml_ud_header_t*)pd;
int ref, ptype;
- if (IS_ATSC(hdr->atsc_flag)) {
+ if (IS_ATSC(hdr->atsc_flag) ) {
aml_ud_header_t *nhdr;
uint8_t *pp, t;
uint32_t v;
@@ -351,15 +483,16 @@ static int aml_process_mpeg_userdata(AM_USERDATA_Device_t *dev, uint8_t *data, i
ref = (v >> 16) & 0x3f;
ptype = (v >> 26) & 7;
- /*AM_DEBUG(0, "CC header: %02x %02x %02x %02x %02x %02x %02x %02x",
- pd[0], pd[1], pd[2], pd[3], pd[4], pd[5], pd[6], pd[7]);
- */
+// AM_DEBUG(0, "CC header digi: %02x %02x %02x %02x %02x %02x %02x %02x",
+// pd[0], pd[1], pd[2], pd[3], pd[4], pd[5], pd[6], pd[7]);
+
pd += sizeof(aml_ud_header_t);
left -= sizeof(aml_ud_header_t);
while (left >= 8) {
if (left >= (int)sizeof(aml_ud_header_t)) {
nhdr = (aml_ud_header_t*)pd;
+
if (IS_ATSC(nhdr->atsc_flag)) {
aml_mpeg_userdata_package(dev, ref, ptype, pp, pl);
@@ -481,6 +614,8 @@ static void* aml_userdata_thread (void *arg)
if (ud->format == MPEG_CC_TYPE) {
r = aml_process_mpeg_userdata(dev, pd, left);
+ } else if (ud->format == SCTE_CC_TYPE) {
+ r = aml_process_scte_userdata(dev, pd, left);
} else if (ud->format != INVALID_TYPE) {
r = aml_process_h264_userdata(dev, pd, left, poc_block.poc_number);
} else {
@@ -520,6 +655,7 @@ static AM_ErrorCode_t aml_open(AM_USERDATA_Device_t *dev, const AM_USERDATA_Open
ud->running = AM_TRUE;
ud->cc_num = 0;
ud->curr_poc = -1;
+ ud->scte_enable = 1;
r = pthread_create(&ud->th, NULL, aml_userdata_thread, (void*)dev);
if (r) {
diff --git a/lib32/libam_ver.so b/lib32/libam_ver.so
index 48d9464..376edad 100755
--- a/lib32/libam_ver.so
+++ b/lib32/libam_ver.so
@@ -1,4 +1,4 @@
-ELF
+ELF

0å3ÿ/áÐKâ
@@ -97,8 +97,8 @@ B¿&¼ñ
óÿ°°¬€:óÿ°°°€8óÿ°°¨€Nóÿ°„€Xóÿ°°°€xóÿ° „€üóÿ°°ª€€ôÿ°°°€˜ôÿ° „€4õÿ°«
-€˜ùÿ°°¬€Ôùÿ°°°€þÿ
+€˜ùÿ°°¬€Ôùÿ°°°€þÿ
A 
- "&Dlibam_ver.so
+ "&Dlibam_ver.so
diff --git a/lib64/libam_ver.so b/lib64/libam_ver.so
index ae9dc13..edc263e 100755
--- a/lib64/libam_ver.so
+++ b/lib64/libam_ver.so
@@ -1,2 +1,2 @@
-ELF
-
+ELF
+
diff --git a/libam_ver.so b/libam_ver.so
index 9437fcc..7408b98 100755
--- a/libam_ver.so
+++ b/libam_ver.so
@@ -1,7 +1,6 @@
ELF
-0å3ÿ/áÐKâ
+0å3ÿ/áÐKâ
A 
- "Dlibam_ver.so
-Ä
+ "Dlibam_ver.so