author | Gong 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) |
commit | 0e3343d7f936361567270e859c0edbbb4c8a5154 (patch) | |
tree | 8f70f569f5ecc2152a11b99b74980e204a3a8549 | |
parent | a29ba7e98846b2e771337b7dead9cba959fa5672 (diff) | |
download | dvb-0e3343d7f936361567270e859c0edbbb4c8a5154.zip dvb-0e3343d7f936361567270e859c0edbbb4c8a5154.tar.gz dvb-0e3343d7f936361567270e859c0edbbb4c8a5154.tar.bz2 |
DTVCC: support scte [1/1]
PD# 157054
Change-Id: Ice1e8bb0d90f60612d26a5fc8ffb5cbb2934d212
-rw-r--r-- | am_adp/am_userdata/aml/aml.c | 146 | ||||
-rwxr-xr-x | lib32/libam_ver.so | 6 | ||||
-rwxr-xr-x | lib64/libam_ver.so | 4 | ||||
-rwxr-xr-x | libam_ver.so | 5 |
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 |