#include "cc_config.h" #include "cc_type.h" #include "cc_def.h" #include "cc_private.h" #define MAX_NUM_SAVED_DATA 128 #define DCC_ATSC_ID 0x47413934 #define DCC_AFD_ID 0x44544731 static struct { //708 tDCC_DefWin rcv_dfw; tDCC_WinAttr rcv_wa; tDCC_PenAttr rcv_pa; UINT8 saved_data[MAX_NUM_SAVED_DATA*2]; UINT8 num_saved_data; BOOL is_set_ETX; // ETX Ä¿¸Çµå ¼ö½Å ¿©ºÎ, ETXÀÌÈÄ text(GX)¸¦ ¹«½ÃÇϱâ À§ÇØ »ç¿ë // ETX ¼ö½Å½Ã TRUE, CxÄ¿¸Çµå ¼ö½Å½Ã FALSE //608 BOOL is_feeding_608; //common UINT8 service_num; UINT32 last_rcvd_ms[eDCC_S_NUM]; //service on ¿©ºÎ¸¦ üũÇϱâ À§ÇÔ. // callback tDCC_InfoCallback info_cb; } p_front_attr; #define ATTR(i) p_front_attr.i #if ENABLE_AFD static BOOL p_b_afd_on=FALSE; static void (*p_fn_afd_callback)(UINT8); static UINT8 p_afd_format=0xff; static UINT32 p_afd_rx_count; #if ENABLE_AFD_BARDATA // note that bar data implementation is on going. struct { UINT16 top, bottom, left, right; } p_afd_bardata; static void (*p_fn_afd_bardata_callback)(UINT16 t, UINT16 b, UINT16 l, UINT16 r); #endif //#define AFD_TIMER_ID 0xafdafd //void p_afd_timer_proc(UINT32 timer, UINT32 param); void DCC_SetAFDOn(BOOL); BOOL DCC_GetIsAFDOn(); void DCC_SetAFDFormat(UINT8 format); UINT8 DCC_GetAFDFormat(); #endif #if 0 __CC_UTIL__() {} #endif static UINT8 p_make_color(UINT8 r, UINT8 g, UINT8 b) { r=r>=2?1:0; g=g>=2?1:0; b=b>=2?1:0; return r | (g<<1) | (b<<2); } void p_bit_reverse( UINT8 src, UINT8 *dest ) { *dest = (src << 7) + ((src & 0x2) << 5) + ((src & 0x4) << 3) + ((src & 0x8) << 1) + ((src & 0x10) >> 1) + ((src & 0x20) >> 3) + ((src & 0x40) >> 5) + ((src & 0x80) >> 7); } BOOL p_check_parity_error(BOOL bOddParity,UINT8 ch_char) { //leon 2004.04.19 NTSC CC´Â odd parity¸¦ °¡Á®¾ß µÈ´Ù. // BOOL bReturn=FALSE; BOOL bOdd=0; int parity=0; int i; for(i=0;i<8;i++){ parity+=(ch_char>>i)&0x01; } bOdd=parity%2; if(bOddParity && !bOdd){//odd parity bReturn=TRUE;//parity error }else if(!bOddParity && bOdd){//even parity bReturn=TRUE;//parity error } // dcm_Print( "p err!\n" ); return bReturn; } #if 0 // zooyouny 100701 : »ç¿ëµÇ´Â °÷ÀÌ ¾øÀ½ static int p_get_cmd_len(UINT8 cmd) { return 0; } #endif #if 0 __708_CC_PARSE__() {} #endif static int p_parse_c0(UINT8 *data, int size) { int idx=0; CCPRINT("parse708", "Parse C0(%s)\n", CC_C0_NAME(data[idx])); ATTR(is_set_ETX) = FALSE; switch(data[idx]) { case eDCC_C0_NUL : //Àü´ÞÇÏÁö ¾ÊÀ½. break; case eDCC_C0_ETX : //ATTR(is_set_ETX) = TRUE; //etx´Â ´ÙÀ½ command°¡ ¿Ã ¶§±îÁö ¹öÆÛ¿¡ ÀÖ´Â data¸¦ ¸ðµÎ flushÇÔ //µû¶ó¼­ µ¥ÀÌÅͰ¡ ¿Ã ¶§¸¶´Ù »Ñ·ÁÁÖ´Â ½Ã½ºÅÛ¿¡¼­´Â Àǹ̾ø´Â commandÀÓ break; case eDCC_C0_BS : case eDCC_C0_FF : case eDCC_C0_CR : case eDCC_C0_HCR : DCCExec_ProcessMsg(eCMD_C0, 0, data[idx], 0); break; case eDCC_C0_P16 : if(size<3) return -1; #if USE_KOR_CC /* °¡²û ÀÌÀü packet¿¡ 0x18Äڵ尡 ¿ÔÀ¸¸é¼­ ´Ù½Ã ¹Ýº¹Çؼ­ 0x18ÀÌ ¿À´Â °æ¿ì ÀÖÀ½ ÀÌ °æ¿ì¿¡ ´ëÇØ¼­ ¿¹¿Ü 󸮸¦ ÇØ¾ßÇÔ */ #if USE_MODIFY_P16 if(data[idx+1]==eDCC_C0_P16) { CCPRINT("parse708", "contineous p16 code\n"); return 1; } #endif DCCExec_ProcessMsg(eCMD_GX, eDCC_OPT_P16, data[idx+1]<<8 | data[idx+2], 0); #endif idx+=2; break; default: if(data[idx]<0x10) idx=1; else if(data[idx]<0x18) idx=2; else idx=3; if(size>3; ATTR(rcv_dfw).rl=(data[idx]&0x10)>>4; ATTR(rcv_dfw).v=(data[idx]&0x20)>>5; ATTR(rcv_dfw).av=data[++idx]&0x7f; ATTR(rcv_dfw).rp=(data[idx]&0x80)>>7; ATTR(rcv_dfw).ah=data[++idx]; ATTR(rcv_dfw).rc=data[++idx]&0xf; ATTR(rcv_dfw).ap=(data[idx]&0xf0)>>4; ATTR(rcv_dfw).cc=data[++idx]&0x3f; ATTR(rcv_dfw).ps=data[++idx]&0x7; ATTR(rcv_dfw).ws=(data[idx]&0x38)>>3; CCPRINT("parse708ex", "\tid(%d), p(%d), cl(%d), rl(%d)\n", ATTR(rcv_dfw).id, ATTR(rcv_dfw).p, ATTR(rcv_dfw).cl, ATTR(rcv_dfw).rl); CCPRINT("parse708ex", "\tv(%d), av(%d), rp(%d), ah(%d)\n", ATTR(rcv_dfw).v, ATTR(rcv_dfw).av, ATTR(rcv_dfw).rp, ATTR(rcv_dfw).ah); CCPRINT("parse708ex", "\trc(%d), ap(%d), cc(%d), ps(%d)\n", ATTR(rcv_dfw).rc, ATTR(rcv_dfw).ap, ATTR(rcv_dfw).cc, ATTR(rcv_dfw).ps); CCPRINT("parse708ex", "\tws(%d)\n", ATTR(rcv_dfw).ws); DCCExec_ProcessMsg(eCMD_DFX, 0, (UINT32)&ATTR(rcv_dfw), 0); break; case eDCC_C1_CLW : if(size<2) return -1; //ÇØ´ç windowÀÇ ¹è°æÀ» Áö¿î´Ù. CCPRINT("parse708ex", "\twin(0x%x)\n", data[idx+1]); DCCExec_ProcessMsg(eCMD_CLW, 0, data[++idx], 0); break; case eDCC_C1_DLW : if(size<2) return -1; CCPRINT("parse708ex", "\twin(0x%x)\n", data[idx+1]); DCCExec_ProcessMsg(eCMD_DLW, 0, data[++idx], 0); break; case eDCC_C1_DSW : if(size<2) return -1; CCPRINT("parse708ex", "\twin(0x%x)\n", data[idx+1]); DCCExec_ProcessMsg(eCMD_DSW, 0, data[++idx], 0); break; case eDCC_C1_HDW : if(size<2) return -1; CCPRINT("parse708ex", "\twin(0x%x)\n", data[idx]); DCCExec_ProcessMsg(eCMD_HDW, 0, data[++idx], 0); break; case eDCC_C1_TGW : if(size<2) return -1; CCPRINT("parse708ex", "\twin(0x%x)\n", data[idx]); DCCExec_ProcessMsg(eCMD_TGW, 0, data[++idx], 0); break; case eDCC_C1_SWA : if(size<5) return -1; idx++; ATTR(rcv_wa).fc= p_make_color((data[idx]&0x30)>>4, (data[idx]&0xc)>>2, data[idx]&0x3); ATTR(rcv_wa).fo=(data[idx]&0xc0)>>6; idx++; ATTR(rcv_wa).bc= p_make_color((data[idx]&0x30)>>4, (data[idx]&0xc)>>2, data[idx]&0x3); ATTR(rcv_wa).bt=(data[idx]&0xc0)>>6 | (data[idx+1]&0x80)>>5; ATTR(rcv_wa).j=data[++idx]&0x3; ATTR(rcv_wa).sd=(data[idx]&0xc)>>2; ATTR(rcv_wa).pd=(data[idx]&0x30)>>4; ATTR(rcv_wa).ww=(data[idx]&0x40)>>6; ATTR(rcv_wa).de=data[++idx]&0x3; ATTR(rcv_wa).ed=(data[idx]&0xc)>>2; ATTR(rcv_wa).es=(data[idx]&0xf0)>>4; CCPRINT("parse708ex", "\tfc(%d), fo(%d), bc(%d), bt(%d)\n", ATTR(rcv_wa).fc, ATTR(rcv_wa).fo, ATTR(rcv_wa).bc, ATTR(rcv_wa).bt); CCPRINT("parse708ex", "\tj(%d), sd(%d), pd(%d), ww(%d)\n", ATTR(rcv_wa).j, ATTR(rcv_wa).sd, ATTR(rcv_wa).pd, ATTR(rcv_wa).ww); CCPRINT("parse708ex", "\tde(%d), ed(%d), es(%d)\n", ATTR(rcv_wa).de, ATTR(rcv_wa).ed, ATTR(rcv_wa).es); DCCExec_ProcessMsg(eCMD_SWA, 0, (UINT32)&ATTR(rcv_wa), 0); break; case eDCC_C1_SPA : if(size<3) return -1; ATTR(rcv_pa).s=data[++idx]&0x3; ATTR(rcv_pa).o=(data[idx]&0xc)>>2; ATTR(rcv_pa).tt=(data[idx]&0xf0)>>4; ATTR(rcv_pa).fs=data[++idx]&0x7; ATTR(rcv_pa).et=(data[idx]&0x38)>>3; ATTR(rcv_pa).u=(data[idx]&0x40)>>6; ATTR(rcv_pa).i=(data[idx]&0x80)>>7; CCPRINT("parse708ex", "\ts(%d), o(%d), tt(%d), fs(%d)\n", ATTR(rcv_pa).s, ATTR(rcv_pa).o, ATTR(rcv_pa).tt, ATTR(rcv_pa).fs); CCPRINT("parse708ex", "\tet(%d), u(%d), i(%d)\n", ATTR(rcv_pa).et, ATTR(rcv_pa).u, ATTR(rcv_pa).i); DCCExec_ProcessMsg(eCMD_SPA, 0, (UINT32)&ATTR(rcv_pa), 0); break; case eDCC_C1_SPC : if(size<4) return -1; idx++; ATTR(rcv_pa).fc= p_make_color((data[idx]&0x30)>>4, (data[idx]&0xc)>>2, data[idx]&0x3); ATTR(rcv_pa).fo=(data[idx]&0xc0)>>6; idx++; ATTR(rcv_pa).bc= p_make_color((data[idx]&0x30)>>4, (data[idx]&0xc)>>2, data[idx]&0x3); ATTR(rcv_pa).bo=(data[idx]&0xc0)>>6; idx++; ATTR(rcv_pa).ec= p_make_color((data[idx]&0x30)>>4, (data[idx]&0xc)>>2, data[idx]&0x3); CCPRINT("parse708ex", "\tfc(%d), fo(%d), bc(%d), bo(%d)\n", ATTR(rcv_pa).fc, ATTR(rcv_pa).fo, ATTR(rcv_pa).bc, ATTR(rcv_pa).bo); CCPRINT("parse708ex", "\tec(%d)\n", ATTR(rcv_pa).ec); DCCExec_ProcessMsg(eCMD_SPC, 0, (UINT32)&ATTR(rcv_pa), 0); break; case eDCC_C1_SPL : if(size<3) return -1; CCPRINT("parse708ex", "\tspl row(%d), col(%d)\n", data[idx+1]&0xf, data[idx+2]&0x3f); DCCExec_ProcessMsg(eCMD_SPL, 0, data[idx+1]&0xf, data[idx+2]&0x3f); idx+=2; break; case eDCC_C1_DLY : if(size<2) return -1; CCPRINT("parse708ex", "\tdly(%d)\n", data[idx+1]); DCCExec_ProcessMsg(eCMD_DLY, 0, data[++idx], 0); break; case eDCC_C1_DLC : DCCExec_ProcessMsg(eCMD_DLC, 0, 0, 0); break; case eDCC_C1_RST : DCCExec_ProcessMsg(eCMD_RST, 0, 0, 0); break; default: ;//±×´ë·Î ó¸®ÇÏ¸é µÊ. } return idx+1; } static int p_parse_c2(UINT8 *data, int size) { int idx=0; ATTR(is_set_ETX) = FALSE; if(data[idx]<0x8) idx=1; else if(data[idx]<0x10) idx=2; else if(data[idx]<0x18) idx=3; else idx=4; if(size 0x5ff·Î º¯°æÇÔ. // DCCExec_ProcessMsg(eCMD_GX, 0, 0x5ff, 0); // else DCCExec_ProcessMsg(eCMD_GX, 0, data[0], 0); } return 1; } static int p_parse_g1(UINT8 *data, int size) { if (ATTR(is_set_ETX) == FALSE) DCCExec_ProcessMsg(eCMD_GX, 0, data[0], 0); return 1; } static int p_parse_g2(UINT8 *data, int size) { //g2 ÄÚµå Áß »ç¿ëµÇÁö ¾Ê´Â ÄÚµå´Â ¹«½Ã¸¦ ÇØ¾ß ÇÔ. //0x500¹ø´ë´Â »ç¿ëµÇÁö ¾ÊÀ½.. static UINT8 used[]= { 0x20, 0x21, 0x25, 0x2a, 0x2c, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x39, 0x3a, 0x3c, 0x3d, 0x3f, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f }; int i; BOOL bmatched=FALSE; for(i=0; i=MAX_NUM_SAVED_DATA) { //buffer is full CCPRINT("warn", "buffer is full(saved size : %d, in size : %d\n", ATTR(num_saved_data), size); DCCExec_ProcessMsg(eCMD_BUF_FULL, 0, 0, 0); } //¿ì¼± saved data¿¡ ÀúÀåÇÑ ÈÄ Ã³¸®Çϵµ·Ï ÇÔ memcpy(ATTR(saved_data)+ATTR(num_saved_data), data, size); ATTR(num_saved_data)+=size; for(idx=0; idx>6; int pkt_size=data[0]&0x3f; int idx; int blk_size, service_num; CCPRINT("dmx708", "size : %d, pkt_size:%d\n", size, pkt_size); CCPRINT("dmx708", "prev_seq_no:%d, seq_no:%d\n", prev_seq_no, seq_no); if(prev_seq_no!=-1 && (prev_seq_no+1)%4!=seq_no) { CCPRINT("warn", "seq num error(prev(%d), cur(%d)\n", prev_seq_no, seq_no); #if IGNORE_SEQ_NUM==0 //bad seq no..Update ÇÊ¿äÇÔ. prev_seq_no=-1; //ÇöÀç ¸ðµç »óŸ¦ ÃʱâÈ­ÇÔ.--> ÇöÀç »óŰ¡ 708ÀÏ °æ¿ì¸¸. if(ATTR(service_num)>=eDCC_S_CS1 && ATTR(service_num)<=eDCC_S_CS6) { DCCExec_ProcessMsg(eCMD_RST, 0, 0, 0); } return -1; #endif } prev_seq_no=seq_no; if(pkt_size==0){ pkt_size=127; } else pkt_size=pkt_size*2-1; if(pkt_size > size-1) { /* ½ÇÁ¦º¸´Ù Àû°Ô ¹ÞÀº °æ¿ì */ #if DISCARD_UNCORRECTED_PKT_SIZE //À߸øµÈ packetÀ̹ǷΠ¹ö¸² CCPRINT("dmx708", "packet size is bad(hdr len(%d), rcvd_len(%d)\n", pkt_size, size); return -1; #else //neverdai. pkt size º¸´Ù size°¡ ÀÛÀ» ¶§ pkt_size¸¦ Á¶Á¤ÇØ¾ß ÇÔ. pkt_size=size-1; CCPRINT("dmx708", "calculate packet size again!!\n"); #endif } else if(pkt_size < size-1) { /* ½ÇÁ¦º¸´Ù ¸¹ÀÌ ¹ÞÀº °æ¿ì */ #if DISCARD_UNCORRECTED_PKT_SIZE CCPRINT("dmx708", "packet size is bad(hdr len(%d), rcvd_len(%d)\n", pkt_size, size); return -1; #else //neverdai. pkt size º¸´Ù size°¡ ÀÛÀ» ¶§ pkt_size¸¦ Á¶Á¤ÇØ¾ß ÇÔ. pkt_size=size-1; CCPRINT("dmx708", "calculate packet size again!!\n"); #endif } for(idx=1; idx>5; if(service_num==0x7 && blk_size!=0) { service_num=data[idx++]&0x3f; #if DISCARD_WHEN_BAD_EXT_SERVICE_NUM if(service_num<=6) { idx+=blk_size; CCPRINT("warn", "demux_708 service number is not fair!!\n"); continue; } #endif } if(service_num==0) { if(blk_size==0) break;//null service block hdr #if DISCARD_WHEN_BAD_NULL_BLOCK else break; #endif } CCPRINT("dmx708", "service num : %d, size : %d\n", service_num, blk_size); if(blk_size>pkt_size+1-idx) { #if DISCARD_WHEN_PACKET_BLOCK_MISMATCH CCPRINT("dmx708", "block size and packet size is not matched..\n"); break; #else blk_size=pkt_size+1-idx; //blk_size Á¶Àý. #endif } //¼³Á¤µÈ service¸¸ ó¸®ÇÔ. if(ATTR(service_num)-eDCC_S_CS1+1==service_num) { //DCCExec_ProcessMsg(eCMD_SERVICE_ON, 0, service_num, 0); p_parse_708(&data[idx], blk_size); DCCMain_SendCmd(eCMD_SET_TIMER, eDCC_OPT_TIMER_ONESHOT, TIMER_ID_CLEAR_SCREEN, TIMER_CLEAR_SCREEN_DURATION); } if(service_num>=1 && service_num<=6) ATTR(last_rcvd_ms)[eDCC_S_CS1+service_num-1]=DCCDDI_GetCurMs(); idx+=blk_size; } return 0; } static BOOL p_checksum_byte(UINT8 data) { int i; int sum; for(i=0, sum=0; i<8; i++) { sum+=(data>>i)&0x1; } if(sum&0x1) //odd return TRUE; return FALSE; } static void p_demux_608_data(UINT8 field, UINT8 d1, UINT8 d2) { static int rcv_sm[2]={eDCC_S_NONE, eDCC_S_NONE}; if(!p_checksum_byte(d1) || !p_checksum_byte(d2)) { CCPRINT("warn", "608 byte checksum error(d1:%x,d2:%x)\n", d1, d2); return; } d1=(d1&(~0x80)); d2=(d2&(~0x80)); if(d1==0 && d2==0) return; if(d1==0xff && d2==0xff) return; CCPRINT("dmx608", "demux 608 data(field:%d, 0x%x,0x%x)\n", field, d1, d2); if(field>1) field=1; if(d1>=0x10 && d1<0x20) { if(d2==eDCC_C_RU2 || d2==eDCC_C_RU3 || d2==eDCC_C_RU4 || d2==eDCC_C_RCL || d2==eDCC_C_RDC) { //CC Mode if(d1==0x14 && field==0) rcv_sm[field]=eDCC_S_CC1; else if(d1==0x1c && field==0) rcv_sm[field]=eDCC_S_CC2; else if(d1==0x15 && field==1) rcv_sm[field]=eDCC_S_CC3; else if(d1==0x1d && field==1) rcv_sm[field]=eDCC_S_CC4; else if(d1==0x14 || d1==0x1c || d1==0x15 || d1==0x1d) rcv_sm[field]=eDCC_S_NONE; } else if(d2==eDCC_C_TR || d2==eDCC_C_RTD) { //Text Mode if(d1==0x14 && field==0) rcv_sm[field]=eDCC_S_T1; else if(d1==0x1c && field==0) rcv_sm[field]=eDCC_S_T2; else if(d1==0x15 && field==1) rcv_sm[field]=eDCC_S_T3; else if(d1==0x1d && field==1) rcv_sm[field]=eDCC_S_T4; else if(d1==0x14 || d1==0x1c || d1==0x15 || d1==0x1d) rcv_sm[field]=eDCC_S_NONE; } if(rcv_sm[field]==eDCC_S_NONE) { //󸮸¦ ÇÒ Çʿ䰡 ¾øÀ½. CCPRINT("dmx608", "receive service mode is none\n"); return; } } else if(d1<0x10) { #if ENABLE_XDS //xds Mode if(field==1) { //todo xds ó¸® } #endif return; } ATTR(last_rcvd_ms)[rcv_sm[field]]=DCCDDI_GetCurMs(); //¹ÞÀº ½Ã°¢ ÀúÀå if(rcv_sm[field]==ATTR(service_num)) { p_parse_608_data(field, d1, d2); DCCMain_SendCmd(eCMD_SET_TIMER, eDCC_OPT_TIMER_ONESHOT, TIMER_ID_CLEAR_SCREEN, TIMER_CLEAR_SCREEN_DURATION_608); } } #if 0 __PICTURE_UD__() {} #endif static void p_print_pic_ud(tDCC_PicUDRaw *pic_ud_raw) { int i; UINT8 *buf=pic_ud_raw->data; BOOL is_print=FALSE; #if 0 for(i=0, is_print=FALSE; i<(buf[5]&0x1f); i++) { if(((buf[7+i*3]&0x7)==0x7) || ((buf[7+i*3]&0x7)==0x6)) {is_print=TRUE; break;} } if(!is_print) return; #endif CCPRINT("ud2", "====================================================\n"); CCPRINT("ud3", "ATSC_ID : [%02x %02x %02x %02x], type : [%02x], cc_cnt : %d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]&0x1f); for(i=0; i<(buf[5]&0x1f); i++) { if(7+i*3+2>=pic_ud_raw->size) { CCPRINT("udex2", "[%d/%d]size is small(size:%d)\n", i, buf[5]&0x1f, pic_ud_raw->size); break; } if(!(buf[7+i*3]&0x4)) { CCPRINT("udex3", "invalid(0x%x)\n", buf[7+i*3]); //continue; } else if((buf[7+i*3]&0x3)==0x3) { CCPRINT("ud", "--> CC START : cnt[%d][%02x %02x %02x]\n", buf[5]&0x1f, buf[7+i*3], buf[7+i*3+1], buf[7+i*3+2]); CCPRINT("ud1", " SeqNum : %d, PktSize : %d\n", buf[7+i*3+1]>>6, (buf[7+i*3+1]&0x3f)*2-1); CCPRINT("ud1", " service num : %d, block_size : %d\n", buf[7+i*3+2]>>5, buf[7+i*3+2]&0x1f); } else if((buf[7+i*3]&0x3)==0x2) { CCPRINT("ud", " ++ CC DATA : [%d/%d][%02x %02x %02x]\n", i, buf[5]&0x1f, buf[7+i*3], buf[7+i*3+1], buf[7+i*3+2]); } else { CCPRINT("ud2", " ++ CC EXT : [%d/%d][%02x %02x %02x]\n", i, buf[5]&0x1f, buf[7+i*3], buf[7+i*3+1], buf[7+i*3+2]); } } CCPRINT("udex3", "====================================================\n"); } static int p_parse_pic_ud(tDCC_PicUDRaw *pic_ud_raw, tDCC_PicUD *pic_ud) { UINT32 temp; int i; #if ENABLE_AFD UINT8 tmpBuf[2]; #endif DCCUtil_InitBitBuf(pic_ud_raw->data, pic_ud_raw->size); CCPRINT("parse_ud", "(id:%d)parse pic ud(size : %d)\n", pic_ud_raw->ms_rcv, pic_ud_raw->size); p_print_pic_ud(pic_ud_raw); if(DCCUtil_CheckBits(32)) return -1; if(DCCUtil_NextBits(32)==DCC_ATSC_ID) { DCCUtil_GetBits(32); //ATSC_ID if(DCCUtil_CheckBits(8)) return -1; temp=DCCUtil_GetBits(8); //User data type code if(temp==0x3) { pic_ud->ud_type=eDCC_UD_TC_708; } else if(temp==0x4) { pic_ud->ud_type=eDCC_UD_TC_608; } else { pic_ud->ud_type=eDCC_UD_TC_UNKNOWN; CCPRINT("parse_ud", "!! pic user data type code is not supported(type:0x%x)\n", temp); return -1; } } #if ENABLE_AFD else if(DCC_GetIsAFDOn() && !DCCUtil_CheckBits(32) && DCCUtil_NextBits(32) == DCC_AFD_ID) { DCCUtil_GetBits(32); if(DCCUtil_CheckBits(8)) return -1; tmpBuf[0]=(DCCUtil_GetBits(8)>>6)&0x1; //afd active_format_flag if(DCCUtil_CheckBits(8)) return -1; tmpBuf[1]=DCCUtil_GetBits(8)&0xf; //afd active_format p_afd_rx_count++; //active formatÀ» ó¸®ÇÏ¸é µÊ. if(tmpBuf[1] != DCC_GetAFDFormat()) { //CCPRINT("#### afd is changed : 0x%x --> 0x%x\n", DCC_GetAFDFormat(), tmpBuf[1]); DCC_SetAFDFormat(tmpBuf[1]); #if 1 if(p_fn_afd_callback) (*p_fn_afd_callback)(tmpBuf[1]); #else //callbackÀ» Á÷Á¢ È£ÃâÇÏ´Â °ÍÀº ¹®Á¦°¡ µÇ±â ¶§¹®¿¡ timer task¿¡¼­ ó¸®Çϵµ·Ï ÇÔ. DMW_SYS_SetTimer(AFD_TIMER_ID, 0, p_afd_timer_proc, tmpBuf[1], TRUE); #endif } return -1; } #endif else { #if ENABLE_SCTE20_21 CCPRINT("scte2021"," SCTE 20 data!!\n"); if(DCCUtil_CheckBits(16)) return -1; temp = DCCUtil_GetBits(8); if( temp == 0x03)//user data type 0x03 { // ¿ø·¡´Â 0x81ÀÌ ¸ÂÁö¸¸ Cable Lab(?) or Çʸ³½º ÂÊ¿¡¼­ 0x01·Î ÇØÁֱ⸦ ¿äûÇÔ. // Á¶°Ç : start code = 0x40 && vbi data flag == 1 //if( (tmpBuf[1] = DCCUtil_GetBits(8)) == 0x81 ) // SCTE20(7bits, 0x40) + vbi_data_flag(1) temp = DCCUtil_GetBits(8); if( temp & 0x01) { pic_ud->ud_type=eDCC_UD_TC_SCTE2X; } else { CCPRINT("scte2021"," vbi_data_flag is not 1!!\n"); return -1; } } else{ CCPRINT("scte2021"," SCTE 20 data but it is not avaiable!!\n"); return -1; } #else //ENABLE_SCTE20_21 CCPRINT("scte2021", "!! No ATSC_ID(ATSC:0x%x, but 0x%x\n", DCC_ATSC_ID, DCCUtil_NextBits(32)); return -1; #endif//ENABLE_SCTE20_21 } if(pic_ud->ud_type==eDCC_UD_TC_708) { static BOOL b_cc_started=FALSE; static UINT8 cc_buf[256]; // a service block static int cc_idx=0; // an index for the above service block static int pkt_size=0; // the size of DTVCC packet data //UINT8 v_cc_data_pkt[256]; // a cc data packet, of which cc valid is set //int v_cc_idx=0; // an index for the above cc data packet UINT8 marker_bit = 0; BOOL is_valid; if(DCCUtil_CheckBits(16)) return -1; pic_ud->flags=(UINT8)DCCUtil_GetBits(3); //neverdai flags´Â em_data_flag, cc_data_flag, data_flag·Î µÇ¾îÀÖ´Ù. //¿©±â¼­ cc_data¸¸ ó¸®Çϱ⠶§¹®¿¡ cc_data_flag°¡ 0ÀÎÁö 1ÀÎÁö¸¸ È®ÀÎÇÑ´Ù. pic_ud->cc_count=(UINT8)DCCUtil_GetBits(5); pic_ud->em_data=(UINT8)DCCUtil_GetBits(8); if((pic_ud->flags&0x2)==0) { //cc_data_flag°¡ 0ÀÎ °æ¿ì return -1; } for(i=0; icc_count; i++) { if(DCCUtil_CheckBits(24)) return -1; marker_bit = DCCUtil_GetBits(5); //marker bit is_valid=DCCUtil_GetBits(1); temp=DCCUtil_GetBits(2); //cc_type(00,01 : line21 line1,2 10,11 : dtvcc data, start) switch(temp) { case 0x3: //dtvcc start if(b_cc_started) { //ÀúÀåµÇ¾îÀÖ´ø °ÍÀ» ó¸®ÇÔ. if(cc_idx>2){ p_demux_708_data(cc_buf, cc_idx); } b_cc_started=FALSE; pkt_size = 0; } cc_idx=0; if(is_valid) { b_cc_started=TRUE; //v_cc_data_pkt[v_cc_idx++] = (marker_bit << 3) | (is_valid << 2) | temp; cc_buf[cc_idx++]=(UINT8)DCCUtil_GetBits(8); //v_cc_data_pkt[v_cc_idx++] = cc_buf[cc_idx++]; cc_buf[cc_idx++]=(UINT8)DCCUtil_GetBits(8); //v_cc_data_pkt[v_cc_idx++] = cc_buf[cc_idx++]; pkt_size = (cc_buf[0] & 0x3f) * 2; if (pkt_size == 0) pkt_size = 128; } else DCCUtil_GetBits(16); break; case 0x2: //dtvcc data if(!b_cc_started) { //header¸¦ ¹ÞÁö ¸øÇÑ »óÅ¿¡¼­ data¸¦ ¹ÞÀº °æ¿ì.. CCPRINT("parse_ud"," header is not received!!\n"); DCCUtil_GetBits(16); break; } if(cc_idx>=128) { //packet overflow..´õ ÀÌ»ó ¹ÞÁö ¾ÊÀ½. lost packet!! CCPRINT("parse_ud"," lost packet!!\n"); DCCUtil_GetBits(16); break; } if(is_valid) { //v_cc_data_pkt[v_cc_idx++] = (marker_bit << 3) | (is_valid << 2) | temp; cc_buf[cc_idx++]=(UINT8)DCCUtil_GetBits(8); //v_cc_data_pkt[v_cc_idx++] = cc_buf[cc_idx++]; cc_buf[cc_idx++]=(UINT8)DCCUtil_GetBits(8); //v_cc_data_pkt[v_cc_idx++] = cc_buf[cc_idx++]; // Çì´õ¿¡¼­ ÀÐÀº DTVCC ÆÐŶ »çÀÌÁî¿Í ½ÇÁ¦ ÀÐÀº ¹ÙÀÌÆ® ¼ö°¡ °°Àº °æ¿ì ¹Ù·Î ó¸® if (cc_idx >= pkt_size) { p_demux_708_data(cc_buf, cc_idx); cc_idx = 0; b_cc_started = FALSE; pkt_size = 0; } } else { DCCUtil_GetBits(16); #if IGNORE_DTVCC_DATA_INVALID==0 if(cc_idx>2){ p_demux_708_data(cc_buf, cc_idx); } cc_idx=0; b_cc_started=FALSE; pkt_size = 0; #endif } break; case 0x0: #if ENABLE_608_DEMUX if(is_valid) { UINT8 d1 = DCCUtil_GetBits(8); UINT8 d2 = DCCUtil_GetBits(8); //feeding if(ATTR(is_feeding_608)) { DCCDDI_Feeding608(0, d1, d2, FALSE); } p_demux_608_data(0, d1, d2); // v_cc_data_pkt[v_cc_idx++] = d1; // v_cc_data_pkt[v_cc_idx++] = d2; } else DCCUtil_GetBits(16); #else DCCUtil_GetBits(16); #endif break; case 0x1: #if ENABLE_608_DEMUX if(is_valid) { UINT8 d1 = DCCUtil_GetBits(8); UINT8 d2 = DCCUtil_GetBits(8); //feeding if(ATTR(is_feeding_608)) { DCCDDI_Feeding608(1, d1, d2, FALSE); } p_demux_608_data(1, d1, d2); // v_cc_data_pkt[v_cc_idx++] = d1; // v_cc_data_pkt[v_cc_idx++] = d2; } else DCCUtil_GetBits(16); #else DCCUtil_GetBits(16); #endif break; } } #if 0 if (v_cc_idx != 0) DCCExec_ProcessMsg(eCMD_CC_DATA_PACKETS,0, (UINT32)v_cc_data_pkt, v_cc_idx); #endif } #if ENABLE_SCTE20_21 else if(pic_ud->ud_type == eDCC_UD_TC_SCTE2X){ int i; UINT8 temp[2]; UINT8 cc_data[2]; UINT8 cc_count; UINT8 cc_priority, field_number, line_offset, marker_bit; /* zooyouny À§¿¡¼­ ÀоîÁÖµµ·Ï ÇßÀ½ temp[0] = DCCUtil_GetBits(8); temp[1] = DCCUtil_GetBits(8); //user data type°ú vbi data flag´Â user data typeÀ» °áÁ¤ÇÒ ¶§ ¸ÕÀú °Ë»öÇß´Ù. */ cc_count = DCCUtil_GetBits(5)& 0x1F; for(i=0;ipic_structure == 3) { if (pic_ud_raw->top_field_first == 0) { if (field_number == 1) field_number = 2; else if (field_number == 2) field_number = 1; } if (pic_ud_raw->repeat_first_field == 1) { if (pic_ud_raw->top_field_first == 1 && field_number == 3) field_number = 1; else if (pic_ud_raw->top_field_first == 0 && field_number == 3) field_number = 2; } } else if (pic_ud_raw->pic_structure == 0) continue; #endif #if 1 if(cc_data[0]!=0x80 && cc_data[1] != 0x80){ CCPRINT("scte_2021", "field_number:%d, line_offset:%d\n",field_number,line_offset); // zooyouny 100727 : for debuging if (ATTR(info_cb)) { ATTR(info_cb)(eDCC_IT_SCTE20, 0, field_number, (((cc_data[0]&0x7f)<<8)|(cc_data[1]&0x7f))); // "E " ³ª¿À¸é ¸ØÃß°Ô Çϱâ À§ÇÑ µð¹ö±ë ÄÚµå if( ((cc_data[0] & 0x7f) == 0x45) && ((cc_data[1]&0x7f) == 0x20)) cc_data[0] = cc_data[0]; } } if( line_offset == 11 ) //line10 : NTSC field1, line273 : NTSC field2 { if(field_number==1 || field_number==2 ){ if( cc_data[0] == 0 && cc_data[1] == 0 ) continue; /* NTSCÀÏ °æ¿ì odd parityÀ̾î¾ß µÈ´Ù. */ /* zooyouny 100727 : p_demux_608_data ³»ºÎ¿¡¼­ ¼öÇà if( p_check_parity_error( TRUE, cc_data[0] ) || p_check_parity_error( TRUE, cc_data[1] ) ) { CCPRINT("scte_2021","Ignore VBI_DATA cc[%d],[%d]\n", cc_data[0],cc_data[1] ); continue; } */ // if( cc_data[0] != 0x0 || cc_data[1] != 0x0 ) { //iskang //aux cc insert´Â ¿©±â¿¡¼­ ... p_demux_608_data( field_number==1? 0:1, cc_data[0], cc_data[1] ); //feeding if(ATTR(is_feeding_608)) { DCCDDI_Feeding608(field_number==1? 0:1, cc_data[0], cc_data[1], FALSE); } CCPRINT("scte_2021","Send cc data on 608 demux\n"); } } else if(field_number==3) CCPRINT("scte_2021", "Scte20 the repeated field in film mode, field_number (3)\n"); else//field_number==0 CCPRINT("scte_2021", "Scte20 Forbidden field_number (0)\n" ); }//line_offset == 11 else CCPRINT("scte_2021", "line offset is not 11..\n" ); #else p_demux_608_data( field_number-1, cc_data[0], cc_data[1] ); #endif marker_bit = DCCUtil_GetBits(1); } } #endif//ENABLE_SCTE20_21 else { CCPRINT("parse_ud", "Unsupported Format\n"); } #if 1 //ÇϳªÀÇ USER DATA°¡ Á¾·áµÇ¾ú´Ù´Â °ÍÀ» ¾Ë·ÁÁÜ. //feeding if(ATTR(is_feeding_608)) { DCCDDI_Feeding608(1, 0, 0, TRUE); } #endif return 0; } #if 0 __APIs__() {} #endif #if ENABLE_AFD void DCC_SetAFDOn(BOOL bOn) { p_b_afd_on=bOn; } BOOL DCC_GetIsAFDOn() { return p_b_afd_on; } BOOL DCC_SetAFDCallback(void *cb) { p_fn_afd_callback=(void (*)(UINT8))cb; return TRUE; } void DCC_SetAFDFormat(UINT8 format) { p_afd_format=format; } UINT8 DCC_GetAFDFormat() { return p_afd_format; } UINT32 DCC_GetAFDRefreshCount() { return p_afd_rx_count; } #endif //ENABLE_AFD void DCCFront_Init() { static BOOL b_inited=FALSE; if(!b_inited) { //ÃʱâÈ­ ÀÛ¾÷. ATTR(service_num)=eDCC_S_NONE; ATTR(is_set_ETX)=FALSE; b_inited=TRUE; } } int DCCFront_ParsePicUD(tDCC_PicUDRaw *pic_ud_raw, tDCC_PicUD *pic_ud) { return p_parse_pic_ud(pic_ud_raw, pic_ud); } BOOL DCCFront_IsServiceOn(UINT8 service) { if(CC_MS_PASS(ATTR(last_rcvd_ms)[service])>=SERVICE_ON_DURATION) return FALSE; return TRUE; } void DCCFront_SetService(UINT8 service) { ATTR(service_num)=service; } void DCCFront_SetFeeding608(BOOL bon) { ATTR(is_feeding_608)=bon; } void DCCFront_SetCallback(tDCC_InfoCallback func) { ATTR(info_cb)=func; } /* end of file */