#include "DST_ISDBT_ChannelTask.h" #include "DST_CommonAPI.h" #include "DST_HostInterface.h" #include "DST_WinManagerTask.h" //#include "sqlite3.h" #include "dst_eroum_interface.h" #include "DST_DB_Engine.h" #include "DST_DB.h" #include "DST_Parser.h" #include "DST_MultipleStringStructure.h" #include "DST_MemoryDB.h" //#include "DST_OTC_Main.h" DS_U16 DST_GetMHzFrequencybyIndex(int index); int DST_GetAppShortVersionNumber(); void DST_SignalInfoCallBack(int nWidth, int nHeight, int RefreshRate, bool bInterlaced, DHL_SOURCE_ASEPCT Aspect); void DST_VideoFreezeEndProc(); void DST_SBTVDCC_Reset(); DS_U8* JST_Arib2Utf8(DS_U8* strArib, int nLen); #define MAX_EIT_COUNT 4 #define MAX_PMT_COUNT 16 typedef enum { POS_TVCT, POS_STT, POS_PAT, POS_RFUPDATE, POS_CVT, POS_OTC_DII, POS_OTC_DDB, #if CVCT_SUPPORT POS_CVCT, #endif POS_PMT, #if EPG_SUPPORT POS_MGT = POS_PMT + MAX_PMT_COUNT, POS_EIT, POS_ETT = POS_EIT+MAX_EIT_COUNT, #endif } POS_PSIP; static char* GetSiName(int nPos) { switch (nPos) { case POS_TVCT: return "POS_TVCT"; #if CVCT_SUPPORT case POS_CVCT: return "POS_CVCT"; #endif case POS_STT: return "POS_STT"; #if EPG_SUPPORT case POS_MGT: return "POS_MGT"; case POS_EIT: return "POS_EIT"; case POS_ETT: return "POS_ETT"; #endif case POS_PAT: return "POS_PAT"; case POS_PMT: return "POS_PMT"; case POS_RFUPDATE: return "POS_RFUPDATE"; case POS_CVT: return "POS_CVT"; case POS_OTC_DII: return "POS_OTC_DII"; case POS_OTC_DDB: return "POS_OTC_DDB"; } #if EPG_SUPPORT if (nPos > POS_EIT && nPos < POS_EIT + MAX_EIT_COUNT) { return "POS_EIT"; } if (nPos > POS_ETT && nPos < POS_ETT + MAX_EIT_COUNT) { return "POS_ETT"; } #endif if (nPos > POS_PMT && nPos < POS_PMT + MAX_PMT_COUNT) { return "POS_PMT"; } return "Unknown"; } #if 0 ____FREQUENCY___() #endif DS_U8* JST_Uni2Utf8(DS_U16* strUni, int nLen) { if (nLen == 0) return 0; if (strUni == 0) return 0; DS_U16 strTmp16[4097]; memset(strTmp16, 0, sizeof(strTmp16)); if (nLen > 4096) nLen = 4096; memcpy(strTmp16, strUni, nLen * sizeof(DS_U16)); nLen = strlen16(strTmp16); if (nLen == 0) return 0; DS_U8* buff = (DS_U8*)DST_OS_Calloc(nLen*4+1,1); int nPos = 0; int i; for ( i = 0; i < nLen; i++) { DS_U32 uni = strUni[i]; if (uni <= 0x7F) { // 0xxxxxxx buff[nPos] = uni; nPos++; continue; } if (uni <= 0x7FF) { // 110xxxxx 10xxxxxx buff[nPos] = 0xC0 | (uni >> 6); nPos++; buff[nPos] = 0x80 | (uni & 0x3F); nPos++; continue; } if (uni <= 0xFFFF) { // 1110xxxxx 10xxxxxx 10xxxxxx buff[nPos] = 0xE0 | (uni >> 12); nPos++; buff[nPos] = 0x80 | ((uni >> 6) & 0x3F); nPos++; buff[nPos] = 0x80 | (uni & 0x3F); nPos++; continue; } // 11110zzz 10zzxxxx 10xxxxxx 10xxxxxx uni = uni & 0x1FFFFF; buff[nPos] = 0xF0 | (uni >> 18); nPos++; buff[nPos] = 0x80 | ((uni >> 12) & 0x3F); nPos++; buff[nPos] = 0x80 | ((uni >> 6) & 0x3F); nPos++; buff[nPos] = 0x80 | (uni & 0x3F); nPos++; } return buff; } static char* mss2utf8(DS_U8 nLen, DS_U8 *text) { static char strUTF8[4096]; static DS_U16 strUni[4096]; if (nLen == 0 || text == 0) return 0; memset(strUTF8, 0, 4096); memset(strUni, 0,4096*2); DMW_Decode_MultipleStringStructure(nLen, text, (char*)"kor",4096-1, strUni); char *strTmp = (char*)JST_Uni2Utf8(strUni, 4096-1); strcpy(strUTF8, strTmp); DST_OS_Free(&strTmp); return strUTF8; } #if 0 ____MUTE___() #endif static DS_U32 g_VideoMute = 0; static DS_U32 g_AudioMute = 0; static DS_U8 g_AudioVolume = 0; static void CT_VideoMute(DS_U8 nPos, bool bVal) { DS_U32 nVal = bVal ? (g_VideoMute | (1 << nPos)) : (g_VideoMute & (~(1 << nPos))); if (nVal == g_VideoMute) return; if (g_VideoMute == 0 || nVal == 0) DHL_VID_Mute(bVal); g_VideoMute = nVal; } static void CT_AudioMute(DS_U8 nPos, bool bVal) { if (bVal) { g_AudioMute |= (1 << nPos); } else { g_AudioMute &= (~(1 << nPos)); } DHL_AUD_Volume(g_AudioMute ? 0 : g_AudioVolume); } void CT_AudioVolume(DS_U8 nVal) { g_AudioVolume = nVal; DHL_AUD_Volume(g_AudioMute ? 0 : g_AudioVolume); } // mute ó¸® static void CT_ChannelChangeVideoMute(bool bMute) { CT_VideoMute(1, bMute); } static void CT_ChannelChangeAudioMute(bool bMute) { CT_AudioMute(1, bMute); } void CT_WeakSignalMute(bool bMute) { CT_VideoMute(2, bMute); CT_AudioMute(2, bMute); } void CT_AutoScanMute(bool bMute) { CT_VideoMute(3, bMute); CT_AudioMute(3, bMute); } void CT_RatingMute(bool bMute) { CT_VideoMute(4, bMute); CT_AudioMute(4, bMute); } #if 0 ____CHANNEL_MAP___() #endif // CDBSting Class //char* CDBStringAdd(char*strText, const char* strSQL, ...) //{ // if (strSQL == 0) return 0; // va_list ap; // char *z; // va_start(ap, strSQL); // z = sqlite3_vmprintf(strSQL, ap); // va_end(ap); // int nLen = strlen(z) + 1; // char* strTmp = 0; // if (strText) // { // nLen += strlen(strText); // strTmp = (char*)DST_OS_Calloc(nLen,1); // sprintf(strTmp, "%s%s",strText, z); // DST_OS_Free(&strText); // } // else // { // strTmp = (char*)DST_OS_Calloc(nLen,1); // sprintf(strTmp, "%s", z); // } // sqlite3_free(z); // return strTmp; //} //static void CDBStringRun(char* strText) //{ // // insert ¹®À» ½±°Ô ó¸®Çϱâ À§Çؼ­ ¸¶Áö¸· ±ÛÀÚ°¡ ½°Ç¥¸é ½ºÆäÀ̽º·Î º¯È¯ // int nLen = strlen(strText); // if (strText[nLen-1] == ',') // { // strText[nLen-1] = ' '; // CDB db; NewCDB(&db); // db.Query(&db, "%s", strText); // DeleteCDB(&db); // } //// strText[0] = 0; // clear //// DST_OS_Free(&strText); //} static DS_U8* GetMpegDescriptor (DS_U8 *descriptors, DS_U16 len, DS_U8 tag, DS_U8* tag_len) { if (descriptors == 0 || len == 0) return 0; int nPos = 0; *tag_len = 0; while (nPos < len) { DS_U8 nTag = descriptors[nPos]; DS_U8 nLen = descriptors[nPos+1]; if (nPos + nLen + 2 > len) break; // ÀԷµȵ¥ÀÌÅÍÀÇ ¹üÀ§¸¦ ¹ù¾î³ª µ¥ÀÌÅͰ¡ Àִ°æ¿ì if (nTag == tag) { *tag_len = nLen; return &descriptors[nPos]; } nPos += (nLen + 2); } return 0; } static int GetMpegDescriptorCount (DS_U8 *descriptors, DS_U16 len, DS_U8 tag) { if (descriptors == 0 || len == 0) return 0; int nCount = 0; int nPos = 0; while (nPos < len) { DS_U8 nTag = descriptors[nPos]; DS_U8 nLen = descriptors[nPos+1]; if (nPos + nLen + 2 > len) break; // ÀԷµȵ¥ÀÌÅÍÀÇ ¹üÀ§¸¦ ¹ù¾î³ª µ¥ÀÌÅͰ¡ Àִ°æ¿ì if (nTag == tag) nCount++; nPos += (nLen + 2); } return nCount; } // ¹®ÀÚ¿­ µÚÀÇ ' ' Á¦°Å static void Trim(DS_U16 *strText, int nLen) { int i; for ( i=nLen-1; i >= 0; i--) { if (strText[i] == ' ') { strText[i] = 0; continue; } break; } } static bool CT_ChMapUpdateTVCT(DS_U8 RF, TVCT *tvct, DS_U32 CRC32) { if (tvct == 0) return false; if (tvct->numChannels == 0) return false; if (tvct->channel == 0) return false; int i =0; DBLock(true); for (i = 0; i < DB_TVCT_MAX; i++) { if (db_tvct[i].crc == 0) continue; if (db_tvct[i].rf != RF) continue; if (db_tvct[i].crc == CRC32) { DBLock(false); return false; // ÀÌ¹Ì µ¿ÀÏÇÑ TVCT°¡ ä³Î¸Ê¿¡ Àִ°æ¿ìÀÓ } } for (i = 0; i < DB_TVCT_MAX; i++) { if (db_tvct[i].crc == 0) continue; if (db_tvct[i].rf == RF) memset(&db_tvct[i], 0, sizeof(_DB_TVCT_)); } for (i = 0; i < DB_TVCT_MAX; i++) { if (db_tvct[i].crc != 0) continue; db_tvct[i].rf = RF; db_tvct[i].transport_stream_id = tvct->transport_stream_id; db_tvct[i].version_number = tvct->version_number; db_tvct[i].crc = CRC32; break; } for (i = 0; i < DB_TVCT_SUB_MAX; i++) { if (db_tvct_sub[i].program_number == 0) continue; if (db_tvct_sub[i].rf == RF) db_tvct_sub[i].program_number = 0; } tvctChannelPtr_t channel = tvct->channel; for ( i = 0; i < tvct->numChannels; i++, channel++) { Trim(channel->short_name, 7); DS_U8* strName = JST_Uni2Utf8(channel->short_name, 7); char* strExtName = 0; if (GetMpegDescriptorCount(channel->descriptors, channel->descriptor_length, extended_channel_name_tag)) { DS_U8 tag_len = 0; DS_U8 *p = GetMpegDescriptor(channel->descriptors, channel->descriptor_length, extended_channel_name_tag, &tag_len); strExtName = mss2utf8(tag_len, p+2); } int j; for (j = 0; j < DB_TVCT_SUB_MAX; j++) { if (db_tvct_sub[j].program_number != 0) continue; db_tvct_sub[j].rf = RF; if (strName) strcpy(db_tvct_sub[j].short_name, (char*)strName); if (strExtName) strcpy(db_tvct_sub[j].long_name, strExtName); db_tvct_sub[j].major_channel_number = channel->major_channel_number; db_tvct_sub[j].minor_channel_number = channel->minor_channel_number; db_tvct_sub[j].modulation_mode = channel->modulation_mode; db_tvct_sub[j].carrier_frequency = channel->carrier_frequency; db_tvct_sub[j].channel_TSID = channel->channel_TSID; db_tvct_sub[j].program_number = channel->program_number; db_tvct_sub[j].ETM_location = channel->ETM_location; db_tvct_sub[j].access_controlled = channel->access_controlled; db_tvct_sub[j].hidden = channel->hidden; db_tvct_sub[j].show_guide = channel->show_guide; db_tvct_sub[j].service_type = channel->service_type; db_tvct_sub[j].source_id =channel->source_id; break; } DST_OS_Free(&strName); #if 1 if (0) DST_Printf("tvct descriptor = %x\n", (int)channel->descriptors); if (0) DST_Printf("descriptor_length = %d\n", (int)channel->descriptor_length); int i; for ( i = 0; i < channel->descriptor_length; i++) if (0) DST_Printf("%02X ", channel->descriptors[i]); if (0) DST_Printf("\n"); #endif } for (i = 0; i < DB_TVCT_SUB_MAX; i++) { if (db_tvct_sub[i].program_number == 0) continue; if (0) DST_Printf("db_tvct_sub[%d].rf = %d\n", i, db_tvct_sub[i].rf); if (0) DST_Printf("db_tvct_sub[%d].short_name = %s\n", i, db_tvct_sub[i].short_name); if (0) DST_Printf("db_tvct_sub[%d].long_name = %s\n", i, db_tvct_sub[i].long_name); if (0) DST_Printf("db_tvct_sub[%d].major_channel_number = %d\n", i, db_tvct_sub[i].major_channel_number); if (0) DST_Printf("db_tvct_sub[%d].minor_channel_number = %d\n", i, db_tvct_sub[i].minor_channel_number); if (0) DST_Printf("db_tvct_sub[%d].program_number = 0x%X\n", i, db_tvct_sub[i].program_number); if (0) DST_Printf("db_tvct_sub[%d].source_id = %d\n", i, db_tvct_sub[i].source_id); } DBLock(false); return true; } #if CVCT_SUPPORT static bool CT_ChMapUpdateCVCT(DS_U32 RF, CVCT *cvct, DS_U32 CRC32) { if (cvct == 0) return false; if (cvct->numChannels == 0) return false; if (cvct->channel == 0) return false; // CDB db; NewCDB(&db); // db.Query("create table if not exists cvct(rf int unique, transport_stream_id int, version_number int, crc32)"); // db.Query("create table if not exists cvct_sub(" // "rf int, short_name text, long_name text, major_channel_number int, minor_channel_number int, " // "modulation_mode int, carrier_frequency int, channel_TSID int, program_number int, ETM_location int, " // "access_controlled int, hidden int, show_guide int, service_type int, source_id int)"); // db.GetTable(&db, "select crc32 from cvct where rf = %d and crc32 = %d", RF, CRC32); // if(db.GetRow(&db) > 0) // { // DeleteCDB(&db); // return false; // ÀÌ¹Ì µ¿ÀÏÇÑ CVCT°¡ ä³Î¸Ê¿¡ Àִ°æ¿ìÀÓ // } int i =0; for (i = 0; i < DB_CVCT_MAX; i++) { if (db_cvct[i].crc == CRC32) return false; // ÀÌ¹Ì µ¿ÀÏÇÑ CVCT°¡ ä³Î¸Ê¿¡ Àִ°æ¿ìÀÓ } // db.Query(&db, "delete from cvct where rf = %d", RF); for (i = 0; i < DB_CVCT_MAX; i++) { if (db_cvct[i].crc == 0) continue; if (db_cvct[i].rf == RF) memset(&db_cvct[i], 0, sizeof(_DB_CVCT_)); } // db.Query(&db, "insert into cvct values(%d, %d, %d, %d)", // RF, cvct->transport_stream_id, cvct->version_number, (int)CRC32); for (i = 0; i < DB_CVCT_MAX; i++) { if (db_cvct[i].crc != 0) continue; db_cvct[i].rf = RF; db_cvct[i].transport_stream_id = cvct->transport_stream_id; db_cvct[i].version_number = cvct->version_number; db_cvct[i].crc = CRC32; break; } for (i = 0; i < DB_CVCT_SUB_MAX; i++) { if (db_cvct_sub[i].program_number != 0 && db_cvct_sub[i].rf == RF) memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_)); } // char* cvct_sub = CDBStringAdd(0, "insert into cvct_sub values"); cvctChannelPtr_t channel = cvct->channel; int nValidCount = 0; // int i; for ( i = 0; i < cvct->numChannels; i++, channel++) { Trim(channel->short_name, 7); DS_U8* strName = JST_Uni2Utf8(channel->short_name, 7); char *strExtName = 0; if (GetMpegDescriptorCount(channel->descriptors, channel->descriptor_length, extended_channel_name_tag)) { DS_U8 tag_len = 0; DS_U8 *p = GetMpegDescriptor(channel->descriptors, channel->descriptor_length, extended_channel_name_tag, &tag_len); strExtName = mss2utf8(tag_len, p+2); } // ATSC_private_information_descriptor // KLabsŬ¸®¾îÄæDTV_¼Û¼ö½ÅÁ¤ÇÕÇ¥ÁØ_°³Á¤º»-1 bool bCrear = true; if (GetMpegDescriptorCount(channel->descriptors, channel->descriptor_length, 0xAD)) { DS_U8 tag_len = 0; DS_U8 *p = GetMpegDescriptor(channel->descriptors, channel->descriptor_length, 0xAD, &tag_len); if (p[0] == 0xAD) // descriptor_tag { if (p[1] >= 9) // descriptor_length { if (p[2] == 0x54 && p[3] == 0x54 && p[4] == 0x41 && p[5] == 0x30) // format_identifier { if (p[6] >= 1) // private_info_count { if (p[7] == 0x02) // private_info_type Ŭ¸®¾îÄæ DTV¿ë ¼­¼úÀÚ { if (p[8] == 0x02) // private_info_length { DS_U8 ch_frequency_version_number = p[9]; DS_U8 channel_mode = (p[10] >> 4) & 0x0F; DS_U8 resolution = p[10] & 0x0F; if (0) DST_Printf("ch_frequency_version_number = %d channel_mode =%d resolution =%d\n", ch_frequency_version_number, channel_mode, resolution); bCrear = (channel_mode == 0) ? true : false; } } } } } } } bool bValidMajorMinor = true; int major = channel->major_channel_number; int minor = channel->minor_channel_number; if (major < 1000) { bValidMajorMinor = (minor > 0 && minor < 1000); } else if (major >= 0x3F0) { major = (major & 0x0F) * 1024 + minor; minor = 0; } else { bValidMajorMinor = false; } bool bIsCurrentRF = true; { if (channel->carrier_frequency) { DS_U32 freq = 1000000 * DST_GetMHzFrequencybyIndex(RF); //freq = 645000000; // TEST ÄÚµå bIsCurrentRF = (freq == channel->carrier_frequency); } } if (bCrear && bValidMajorMinor && channel->hidden==0 && bIsCurrentRF) { nValidCount++; int j; for (j = 0; j < DB_CVCT_SUB_MAX; j++) { if (db_cvct_sub[j].program_number == 0) { db_cvct_sub[j].rf = RF; if (strName) strcpy(db_cvct_sub[j].short_name, (char*)strName); if (strExtName) strcpy(db_cvct_sub[j].long_name, strExtName); db_cvct_sub[j].major_channel_number = major; db_cvct_sub[j].minor_channel_number = minor; db_cvct_sub[j].modulation_mode = channel->modulation_mode; db_cvct_sub[j].carrier_frequency = channel->carrier_frequency; db_cvct_sub[j].channel_TSID = channel->channel_TSID; db_cvct_sub[j].program_number = channel->program_number; db_cvct_sub[j].ETM_location = channel->ETM_location; db_cvct_sub[j].access_controlled = channel->access_controlled; db_cvct_sub[j].hidden = channel->hidden; db_cvct_sub[j].show_guide = channel->show_guide; db_cvct_sub[j].service_type = channel->service_type; db_cvct_sub[j].source_id =channel->source_id; break; } } // cvct_sub = CDBStringAdd(cvct_sub, "(%d, %Q, %Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d),", // RF, strName, strExtName ? strExtName : "", // major, minor, // channel->modulation_mode, channel->carrier_frequency, // channel->channel_TSID, channel->program_number, // channel->ETM_location, channel->access_controlled, // channel->hidden, channel->show_guide, // channel->service_type, channel->source_id // ); } DST_OS_Free(&strName); #if 1 if (0) DST_Printf("cvct descriptor = %x\n", (int)channel->descriptors); if (0) DST_Printf("descriptor_length = %d\n", (int)channel->descriptor_length); int i; for ( i = 0; i < channel->descriptor_length; i++) if (0) DST_Printf("%02X ", channel->descriptors[i]); if (0) DST_Printf("\n"); #endif } // db.Query(&db, "delete from cvct_sub where rf = %d", RF); // if (nValidCount > 0) CDBStringRun(cvct_sub); // DST_OS_Free(&cvct_sub); #if 1 if (0) DST_Printf("cvct additional_descriptors = %x\n", (int)cvct->additional_descriptors); if (0) DST_Printf("cvct additional_descriptor_length = %d\n", (int)cvct->additional_descriptor_length); // int i; for ( i = 0; i < cvct->additional_descriptor_length; i++) if (0) DST_Printf("%02X ", cvct->additional_descriptors[i]); if (0) DST_Printf("\n"); #endif // DeleteCDB(&db); return true; } #endif // ±âÁ¸ÀÇ PAT°¡ ¾÷µ¥ÀÌÆ® µÇ¸é VCT¸¦ Áö¿ì°í »õ·Î ¹Þ´Â´Ù // ¹Ýȯ°ªÀº °»½Å¿©ºÎÀÌ´Ù. static bool CT_ChMapUpdatePAT(DS_U8 RF, MPEG_PAT *pat, DS_U32 CRC32) { if (pat == 0) return false; int i =0, j = 0; // µ¿ÀÏ RF CRC °Ë»çÇÏ¿© ¾÷µ¥ÀÌÆ® µÈ »óȲÀÎÁö ±¸ºÐÇÔ bool bUpdate = false; DBLock(true); for (i = 0; i < DB_PAT_MAX; i++) { if (db_pat[i].program_number == 0) continue; if (db_pat[i].rf != RF) continue; if (db_pat[i].crc != CRC32) bUpdate = true; break; } // ÇöÀç RF Á¦°Å for (i = 0; i < DB_PAT_MAX; i++) { if (db_pat[i].program_number == 0) continue; if (db_pat[i].rf != RF) continue; db_pat[i].program_number = 0; } for ( i = 0; i < pat->numPrograms; i++) { DS_U16 program_number = pat->programs[i].program_number; DS_U16 pid = pat->programs[i].program_map_PID; for ( j= 0; j < DB_PAT_MAX; j++) { if (db_pat[j].program_number != 0) continue; db_pat[j].rf = RF; db_pat[j].program_number =program_number; db_pat[j].pid = pid; db_pat[j].crc = CRC32; break; } } // PAT¿¡ ¾ø´Â ÇÁ·Î±×·¥³Ñ¹ö´Â Á¦°Å for (i = 0; i < DB_PMT_MAX; i++) { if (db_pmt[i].program_number == 0) continue; bool bFind = false; for ( j= 0; j < DB_PAT_MAX; j++) { if (db_pat[j].program_number == 0) continue; if (db_pmt[i].rf == db_pat[j].rf && db_pmt[i].program_number == db_pat[j].program_number) { bFind = true; break; } } if (bFind == false) db_pmt[i].program_number = 0; // ¾ø´Ù¸é PMT Áö¿ò } DBLock(false); return bUpdate; // ¾÷µ¥ÀÌÆ®ÀÎÁö ¾Æ´ÑÁö ¹Ýȯ } static int g_ChCount = 0; int CT_ChMapCount() { return g_ChCount; } void CT_ChMapUpdate() { DBLock(true); memset(db_channel_db, 0, sizeof(_DB_CHANNEL_DB_) * DB_CHANNEL_DB_MAX); int i,j; // TVCTÀÇ Ã¤³ÎÀ» Ãß°¡ÇÑ´Ù. for (i=0; i < DB_TVCT_SUB_MAX; i++) { if (db_tvct_sub[i].program_number == 0) continue; if (db_tvct_sub[i].hidden != 0) continue; int pcr_pid = 0; int video_pid = 0; int video_type = 0; for (j = 0; j < DB_PMT_MAX; j++) { if (db_pmt[j].program_number == 0) continue; if (db_tvct_sub[i].rf != db_pmt[j].rf) continue; if (db_tvct_sub[i].program_number != db_pmt[j].program_number) continue; pcr_pid = db_pmt[j].pcr_pid; video_pid = db_pmt[j].video_pid; video_type = db_pmt[j].video_type; break; } for (j = 0; j < DB_CHANNEL_DB_MAX; j++) { if (db_channel_db[j].program_number != 0) continue; db_channel_db[j].rf = db_tvct_sub[i].rf; if (strlen(db_tvct_sub[i].short_name)) strcpy(db_channel_db[j].name, db_tvct_sub[i].short_name); // if (strlen(db_tvct_sub[i].long_name)) strcpy(db_channel_db[j].name, db_tvct_sub[i].long_name); db_channel_db[j].major = db_tvct_sub[i].major_channel_number; db_channel_db[j].minor = db_tvct_sub[i].minor_channel_number; db_channel_db[j].program_number = db_tvct_sub[i].program_number; db_channel_db[j].source_id = db_tvct_sub[i].source_id; db_channel_db[j].pcr_pid = pcr_pid; db_channel_db[j].video_pid = video_pid; db_channel_db[j].video_type = video_type; break; } } // TVCT¿¡ ¾ø´Â PMT ä³ÎÀ» Ãß°¡ÇÑ´Ù. for (i = 0; i < DB_PMT_MAX; i++) { if (db_pmt[i].program_number == 0) continue; bool bFind = false; for (j=0; j < DB_TVCT_MAX;j++) { if (db_tvct[j].crc == 0) continue; if (db_tvct[j].rf !=db_pmt[i].rf) continue; bFind = true; break; } if (bFind == true) continue; // TVCT¿¡ ÀÖÀ¸¹Ç·Î ¹«½Ã for (j = 0; j < DB_CHANNEL_DB_MAX; j++) { if (db_channel_db[j].program_number != 0) continue; db_channel_db[j].rf = db_pmt[i].rf; db_channel_db[j].major = (db_pmt[i].rf < 96) ? db_pmt[i].rf +2 : db_pmt[i].rf +4; db_channel_db[j].minor = db_pmt[i].minor; db_channel_db[j].program_number = db_pmt[i].program_number; db_channel_db[j].source_id = 0; db_channel_db[j].pcr_pid = db_pmt[i].pcr_pid; db_channel_db[j].video_pid = db_pmt[i].video_pid; db_channel_db[j].video_type = db_pmt[i].video_type; break; } } // db_channel_db Á¤·ÄÇÑ´Ù. for (i=0; i < DB_CHANNEL_DB_MAX-1; i++) { if (db_channel_db[i].program_number == 0) continue; for (j = i+1; j < DB_CHANNEL_DB_MAX; j++) { if (db_channel_db[j].program_number == 0) continue; if ((db_channel_db[i].major > db_channel_db[j].major) || (db_channel_db[i].major == db_channel_db[j].major && db_channel_db[i].minor > db_channel_db[j].minor) || (db_channel_db[i].major == db_channel_db[j].major && db_channel_db[i].minor == db_channel_db[j].minor && db_channel_db[i].rf > db_channel_db[j].rf)) { struct DB_CHANNEL_DB tmp = db_channel_db[i]; db_channel_db[i] = db_channel_db[j]; db_channel_db[j] = tmp; } } } // ä³Î ¾÷´Ù¿î µðºñ ÃʱâÈ­ memset(db_channel_updn, 0, sizeof(_DB_CHANNEL_UPDN_) * DB_CHANNEL_UPDN_MAX); for (i =0; i db_channel_updn[j].major) || (db_channel_updn[i].major == db_channel_updn[j].major && db_channel_updn[i].minor > db_channel_updn[j].minor) || (db_channel_updn[i].major == db_channel_updn[j].major && db_channel_updn[i].minor == db_channel_updn[j].minor && db_channel_updn[i].rf > db_channel_updn[j].rf)) { struct DB_CHANNEL_UPDN tmp = db_channel_updn[i]; db_channel_updn[i] = db_channel_updn[j]; db_channel_updn[j] = tmp; } } } int nCount = 0; for (i = 0; i < DB_CHANNEL_DB_MAX; i++) { if (db_channel_db[i].program_number) nCount++; } g_ChCount = nCount; DBLock(false); DST_DB_Sync(); } static bool g_bReceiveCCDescriptor = false; static void CT_ChMapUpdatePMTCCDescriptor(DS_U32 RF, DS_U16 prog_num, DS_U8 *descriptors, DS_U16 descriptor_length) { // T(); if(descriptors == 0 || descriptor_length == 0) return; DS_U8 tag_len = 0; DS_U8 *p = GetMpegDescriptor(descriptors, descriptor_length, caption_service_tag, &tag_len ); if (tag_len == 0) return; if (0) DST_Printf("tag_len = %d\n", tag_len); int i; for ( i=0; i < tag_len+2; i++) if (0) DST_Printf("0x%02X ", p[i]); if (0) DST_Printf("\n"); captionServiceDescriptorPtr_t descripPtr = 0; // T(); if (DHL_PSI_ParseCaptionServiceDescriptor(p, &descripPtr)) return; // T(); if (descripPtr == 0) return; // CDB db; NewCDB(&db); if (0) DST_Printf("descripPtr->number_of_services = %d\n", descripPtr->number_of_services); captionServicePtr_t captionService = descripPtr->service; int idx; for( idx = 0 ; idx < descripPtr->number_of_services ; idx++, captionService++) { if(captionService == 0) break; DS_U8 ccId = (captionService->cc_type == cct_line21) ? captionService->cc_id.line21_field : captionService->cc_id.caption_service_number; char strLanguage[4] = "kor"; strcpy(strLanguage, captionService->language); if (0) DST_Printf("strLanguage = %s\n", strLanguage); int i; for ( i = 0; i < MAX_PMT_CC_TABLE_COUNT; i++) { if (pmt_cc_table[i].program_number != 0) continue; pmt_cc_table[i].rf = RF; pmt_cc_table[i].program_number = prog_num; strcpy(pmt_cc_table[i].language,strLanguage); pmt_cc_table[i].cc_type = captionService->cc_type; pmt_cc_table[i].cc_id = ccId; pmt_cc_table[i].easy_reader = captionService->easy_reader; pmt_cc_table[i].wide_aspect_ratio = captionService->wide_aspect_ratio; pmt_cc_table[i].korean_code = captionService->korean_code; if (0) DST_Printf("%s|pmt_cc_table|captionService->cc_type = %d\n", __func__, captionService->cc_type); if (0) DST_Printf("%s|pmt_cc_table|ccId = %d\n", __func__, ccId); if (0) DST_Printf("%s|pmt_cc_table|captionService->easy_reader = %d\n", __func__, captionService->easy_reader); if (0) DST_Printf("%s|pmt_cc_table|captionService->wide_aspect_ratio = %d\n", __func__, captionService->wide_aspect_ratio); if (0) DST_Printf("%s|pmt_cc_table|captionService->korean_code = %d\n", __func__, captionService->korean_code); break; } g_bReceiveCCDescriptor = true; } DHL_PSI_FreeMpegDescriptor(descripPtr); // DeleteCDB(&db); } static void CT_ChMapUpdatePMTAC3AudioDescriptor(DS_U32 RF, DS_U16 prog_num, DS_U16 pid, DS_U8 *descriptors, DS_U16 descriptor_length) { // T(); if (descriptors == 0 || descriptor_length == 0) return; // T(); DS_U8 tag_len = 0; DS_U8 *p = GetMpegDescriptor(descriptors, descriptor_length, AC3_audio_stream_tag, &tag_len ); if (tag_len == 0) return; if (0) DST_Printf("tag_len = %d\n", tag_len); int i; for ( i=0; i < tag_len+2; i++) if (0) DST_Printf("0x%02X ", p[i]); if (0) DST_Printf("\n"); ac3AudioStreamDescriptorPtr_t descripPtr = 0; if (DHL_PSI_ParseAc3AudioStreamDescriptor(p, &descripPtr)) return; if (descripPtr == 0) return; // CDB db; NewCDB(&db); char strLanguage[4] = {0,0,0,0}; strcpy(strLanguage, descripPtr->language); if (0) DST_Printf("strLanguage = %s\n", strLanguage); // ±âÁ¸¿¡ ÀÖµ· µ¿ÀÏÇÑ ÇÁ·Î±×·¥ ³Ñ¹ö pidÀÇ Á¤º¸ ÃʱâÈ­ for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++) { if (pmt_ac3_table[i].program_number == 0) continue; if (pmt_ac3_table[i].rf == (int)RF && pmt_ac3_table[i].program_number == prog_num && pmt_ac3_table[i].pid == pid) pmt_ac3_table[i].program_number = 0; } for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++) { if (pmt_ac3_table[i].program_number != 0) continue; pmt_ac3_table[i].rf = RF; pmt_ac3_table[i].program_number = prog_num; pmt_ac3_table[i].pid = pid; pmt_ac3_table[i].bsmod = descripPtr->bsmod; pmt_ac3_table[i].full_svc = descripPtr->full_svc; pmt_ac3_table[i].langcod = descripPtr->langcod; strcpy(pmt_ac3_table[i].language, strLanguage); if (0) DST_Printf("%s|pmt_ac3_table|%d\n", __func__, i); if (0) DST_Printf("%s|pmt_ac3_table|pid = %d\n", __func__, pid); if (0) DST_Printf("%s|pmt_ac3_table|descripPtr->bsmod = %d\n", __func__, descripPtr->bsmod); if (0) DST_Printf("%s|pmt_ac3_table|descripPtr->full_svc = %d\n", __func__, descripPtr->full_svc); if (0) DST_Printf("%s|pmt_ac3_table|descripPtr->langcod = %d\n", __func__, descripPtr->langcod); break; } } static void CT_ChMapUpdatePMTISO639LanguageDescriptor(DS_U32 RF, DS_U16 prog_num, DS_U16 pid, DS_U8 *descriptors, DS_U16 descriptor_length) { // T(); if (descriptors == 0 || descriptor_length == 0) return; // T(); DS_U8 tag_len = 0; DS_U8 *p = GetMpegDescriptor(descriptors, descriptor_length, ISO_639_language_tag, &tag_len); if (tag_len == 0) return; if (0) DST_Printf("tag_len = %d\n", tag_len); int i; for ( i=0; i < tag_len+2; i++) if (0) DST_Printf("0x%02X ", p[i]); if (0) DST_Printf("\n"); if (p[1] < 4) return; char ISO_639_Language_code[4]; ISO_639_Language_code[0] = (char)p[2]; ISO_639_Language_code[1] = (char)p[3]; ISO_639_Language_code[2] = (char)p[4]; ISO_639_Language_code[3] = 0; DS_U8 audio_type = p[5]; // ±âÁ¸¿¡ ÀÖµ· µ¿ÀÏÇÑ ÇÁ·Î±×·¥ ³Ñ¹ö pidÀÇ Á¤º¸ ÃʱâÈ­ for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++) { if (pmt_iso_table[i].program_number == 0) continue; if (pmt_iso_table[i].rf == (int)RF && pmt_iso_table[i].program_number == prog_num && pmt_iso_table[i].pid == pid) pmt_iso_table[i].program_number = 0; } for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++) { if (pmt_iso_table[i].program_number != 0) continue; pmt_iso_table[i].rf = RF; pmt_iso_table[i].program_number = prog_num; pmt_iso_table[i].pid = pid; strcpy(pmt_iso_table[i].lang, ISO_639_Language_code); pmt_iso_table[i].type = audio_type; if (0) DST_Printf("%s|pmt_iso_table|%d\n", __func__, i); if (0) DST_Printf("%s|pmt_iso_table|pid = %d\n", __func__, pid); if (0) DST_Printf("%s|pmt_iso_table|ISO_639_Language_code = %s\n", __func__, ISO_639_Language_code); if (0) DST_Printf("%s|pmt_iso_table|audio_type = %d\n", __func__, audio_type); break; } } static void CT_PMT_AudioTableUpdate(int rf, int program_number, int pid, int type, int component_tag) { int j; // µ¿ÀÏÇÑ program_number & µ¿ÀÏÇÑ PID for ( j = 0; j < MAX_PMT_AUDIO_TABLE_COUNT; j++) { if (pmt_audio_table[j].program_number == 0) continue; if (pmt_audio_table[j].rf == rf && pmt_audio_table[j].program_number == program_number && pmt_audio_table[j].pid == pid) pmt_audio_table[j].program_number = 0; } // ºó°÷¿¡ ã¾Æ ³Ö´Â´Ù. for ( j = 0; j < MAX_PMT_AUDIO_TABLE_COUNT; j++) { if (pmt_audio_table[j].program_number != 0) continue; pmt_audio_table[j].rf = rf; pmt_audio_table[j].program_number = program_number; pmt_audio_table[j].pid = pid; pmt_audio_table[j].type = type; pmt_audio_table[j].component_tag = component_tag; break; } } static bool CT_ChMapUpdatePMT(DS_U8 RF, MPEG_PMT *pmt, int minor, DS_U32 CRC32) { if (pmt == 0 || pmt->program_number == 0) return false; int i; DBLock(true); for ( i = 0 ; i < MAX_PMT_AUDIO_TABLE_COUNT; i++) { if (pmt_audio_table[i].rf != (int)RF) pmt_audio_table[i].program_number = 0; if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == pmt->program_number) pmt_audio_table[i].program_number = 0; } for ( i = 0 ; i < MAX_PMT_CC_TABLE_COUNT; i++) { if (pmt_cc_table[i].rf != (int)RF) pmt_cc_table[i].program_number = 0; if (pmt_cc_table[i].rf == (int)RF && pmt_cc_table[i].program_number == pmt->program_number) pmt_cc_table[i].program_number = 0; } for ( i = 0 ; i < MAX_PMT_AC3_TABLE_COUNT; i++) { if (pmt_ac3_table[i].rf != (int)RF) pmt_ac3_table[i].program_number = 0; if (pmt_ac3_table[i].rf == (int)RF && pmt_ac3_table[i].program_number == pmt->program_number) pmt_ac3_table[i].program_number = 0; } for ( i = 0 ; i < MAX_PMT_ISO_TABLE_COUNT; i++) { if (pmt_iso_table[i].rf != (int)RF) pmt_iso_table[i].program_number = 0; if (pmt_iso_table[i].rf == (int)RF && pmt_iso_table[i].program_number == pmt->program_number) pmt_iso_table[i].program_number = 0; } for ( i = 0 ; i < DB_PMT_MAX; i++) { // if (db_pmt[i].rf != (int)RF) db_pmt[i].program_number = 0; if (db_pmt[i].rf == (int)RF && db_pmt[i].program_number == pmt->program_number) db_pmt[i].program_number = 0; } DS_U16 video_pid = 0; DS_U8 video_stream_type = 0; for ( i = 0; i < pmt->numStreams; i++) { DS_U16 pid = pmt->streams[i].elementary_PID; if (pid == 0 || pid >= 0x1FFF) continue; DS_U8 stream_type = pmt->streams[i].stream_type; DS_U8 component_tag = pmt->streams[i].component_tag; switch (stream_type) { case StreamType_MPEG1Video: case StreamType_MPEG2Video: case StreamType_MPEG4Video: case StreamType_DC2Video: video_pid = pid; video_stream_type = stream_type; CT_ChMapUpdatePMTCCDescriptor(RF, pmt->program_number, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length); break; case StreamType_MPEG1Audio: case StreamType_MPEG2Audio: case StreamType_MPEG4Audio: case StreamType_AACAudio: case StreamType_AC3Audio: CT_PMT_AudioTableUpdate(RF, pmt->program_number, pid, stream_type, component_tag); CT_ChMapUpdatePMTAC3AudioDescriptor(RF, pmt->program_number, pid, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length); CT_ChMapUpdatePMTISO639LanguageDescriptor(RF, pmt->program_number, pid, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length); break; } } for (i = 0; i < DB_PMT_MAX; i++) // µ¿ÀÏÇÑ Á¤º¸´Â Áö¿î´Ù. { if (db_pmt[i].program_number != 0) continue; db_pmt[i].rf = RF; db_pmt[i].program_number = pmt->program_number; db_pmt[i].pcr_pid = pmt->PCR_PID; db_pmt[i].video_pid = video_pid; db_pmt[i].video_type = video_stream_type; db_pmt[i].minor = minor; db_pmt[i].crc = CRC32; break; } DBLock(false); return true; } #if EPG_SUPPORT static bool CT_ChMapUpdateEIT(DS_U8 rf, EIT *eit, DS_U8 id, DS_U32 CRC32) { if (eit == 0) return false; //CDB db; NewCDB(&db); //db.GetTable(&db, "select crc from eit where rf =%d and id=%d and source_id=%d", rf, id, eit->source_id); int i; bool bFind = false; for (i = 0; i < DB_EIT_MAX; i++) { if (db_eit[i].crc == 0) continue; if (db_eit[i].rf != rf) continue; if (db_eit[i].id != id) continue; if (db_eit[i].source_id != eit->source_id) continue; if (db_eit[i].crc == CRC32) return false; bFind = true; break; } if(bFind) { // db.Query(&db, "delete from eit where rf = %d and id=%d and source_id=%d", rf, id, eit->source_id); for (i = 0; i < DB_EIT_MAX; i++) { if (db_eit[i].crc == 0) continue; if (db_eit[i].rf != rf) continue; if (db_eit[i].id != id) continue; if (db_eit[i].source_id != eit->source_id) continue; memset(&db_eit[i], 0, sizeof(_DB_EIT_)); } // db.Query(&db, "delete from eit_sub where rf = %d and id=%d and source_id=%d", rf, id, eit->source_id); for (i = 0; i < DB_EIT_SUB_MAX; i++) { if (db_eit_sub[i].rf != rf) continue; if (db_eit_sub[i].id != id) continue; if (db_eit_sub[i].source_id != eit->source_id) continue; if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title); memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_)); } } //db.Query(&db, "insert into eit values(%d, %d, %d, %d, %d)", rf, id, eit->source_id, eit->version_number, CRC32); for (i = 0; i < DB_EIT_MAX; i++) { if (db_eit[i].crc != 0) continue; db_eit[i].rf = rf; db_eit[i].id = id; db_eit[i].source_id = eit->source_id; db_eit[i].version_number = eit->version_number; db_eit[i].crc = CRC32; break; } //char* eit_sub = CDBStringAdd(0, "%s", "insert into eit_sub values"); eitEventPtr_t event = eit->event; for ( i = 0; i < eit->numEvents; i++, event++) { // eit_sub = CDBStringAdd(eit_sub, "(%d, %d, %d, %d, %d, %d, %Q),", // rf, id, eit->source_id, event->event_id, event->start_time, event->length_in_seconds, // mss2utf8(event->title_length,event->title)); int j; bool bVacancy = false; // ºóÀÚ¸®°¡ ¾ø´Ù¸é ´Ù¸¥ RFÁ¤º¸¸¦ Áö¿î´Ù for (j =0; j < DB_EIT_SUB_MAX; j++) { if (db_eit_sub[j].source_id) continue; bVacancy = true; break; } if (bVacancy == false) { for (j =0; j < DB_EIT_SUB_MAX; j++) { if (db_eit_sub[j].rf == rf) continue; if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title); memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_)); } } for (j =0; j < DB_EIT_SUB_MAX; j++) { if (db_eit_sub[j].source_id) continue; db_eit_sub[j].rf = rf; db_eit_sub[j].id =id; db_eit_sub[j].source_id = eit->source_id; // not zero db_eit_sub[j].event_id = event->event_id; db_eit_sub[j].start_time = event->start_time; db_eit_sub[j].length_in_seconds = event->length_in_seconds; char* title = mss2utf8(event->title_length,event->title); if (title && strlen(title)) { db_eit_sub[j].title = (char*)DST_OS_Malloc(strlen(title)+1); strcpy(db_eit_sub[j].title, title); } break; } } //if (eit->numEvents > 0) CDBStringRun(eit_sub); //DST_OS_Free(&eit_sub); //DeleteCDB(&db); return true; } static bool CT_ChMapUpdateETT(DS_U8 rf, ETT *ett, DS_U32 crc) { if (ett == 0) return false; int i; for (i=0; i < DB_ETT_MAX; i++) // ÀÌ¹Ì ÀÖ´Â Á¤º¸ÀÎÁö È®ÀÎÇÑ´Ù. { if (db_ett[i].crc == crc) return false; } bool bVacancy = false; // ºóÀÚ¸®°¡ ÀÖ´ÂÁö È®ÀÎÇÑ´Ù. for (i =0; i < DB_ETT_MAX; i++) { if (db_ett[i].crc) continue; bVacancy = true; break; } if (bVacancy == false) // ºóÀÚ¸®°¡ ¾ø´Ù¸é ´Ù¸¥ RF Á¤º¸´Â Áö¿î´Ù. { for (i =0; i < DB_ETT_MAX; i++) { if (db_ett[i].rf == rf) continue; if (db_ett[i].title) DST_OS_Free(&db_ett[i].title); memset(&db_ett[i], 0, sizeof(_DB_ETT_)); } } for (i =0; i < DB_ETT_MAX; i++) // ºóÀÚ¸®°¡ ÀÖ´ÂÁö ´Ù½Ã È®ÀÎÇÑ´Ù. { if (db_ett[i].crc) continue; bVacancy = true; break; } if (bVacancy == false) // EIT¿Í ¿¬°á¾ÈµÈ Á¤º¸´Â Áö¿î´Ù. { for (i=0; i < DB_ETT_MAX; i++) { if (db_ett[i].crc == 0) continue; int j; bool bFind = false; for (j=0; j < DB_EIT_SUB_MAX; j++) { if (db_eit_sub[j].source_id == 0) continue; if (db_ett[i].rf != db_eit_sub[j].rf) continue; if (db_ett[i].source_id != db_eit_sub[j].source_id) continue; if (db_ett[i].event_id != db_eit_sub[j].event_id) continue; bFind = true; break; } if (bFind == false) { if (db_ett[i].title) DST_OS_Free(&db_ett[i].title); memset(&db_ett[i], 0, sizeof(_DB_ETT_)); } } } for (i=0; i < DB_ETT_MAX; i++) // Á¤º¸ Ãß°¡ { if (db_ett[i].crc) continue; db_ett[i].rf = rf; db_ett[i].source_id = (ett->ETM_id>>16) & 0xFFFF; db_ett[i].event_id = (ett->ETM_id>>2) & 0x3FFF ; char* title = mss2utf8(ett->extended_text_message_length,ett->extended_text_message); if (title && strlen(title)) { db_ett[i].title = (char*)DST_OS_Malloc(strlen(title)+1); strcpy(db_ett[i].title, title); } db_ett[i].crc = crc; break; } return true; } #endif // ä³Î½ºÄµ¿¡ ½ÇÆÐÇÑ °æ¿ì ÇØ´ç RF Á¦°Å void JST_DB_Del(DS_U8 nRF) { int i; DBLock(true); #if EPG_SUPPORT for (i =0 ; i < DB_EIT_MAX; i++) { if (db_eit[i].rf != nRF) continue; memset(&db_eit[i], 0, sizeof(_DB_EIT_)); } for (i =0 ; i < DB_EIT_SUB_MAX; i++) { if (db_eit_sub[i].rf != nRF) continue; if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title); memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_)); } for (i =0 ; i < DB_ETT_MAX; i++) { if (db_ett[i].rf != nRF) continue; if (db_ett[i].title) DST_OS_Free(&db_ett[i].title); memset(&db_ett[i], 0, sizeof(_DB_ETT_)); } #endif for (i =0 ; i < DB_PAT_MAX; i++) { if (db_pat[i].rf != nRF) continue; memset(&db_pat[i], 0, sizeof(_DB_PAT_)); } for (i =0 ; i < DB_PMT_MAX; i++) { if (db_pmt[i].rf != nRF) continue; memset(&db_pmt[i], 0, sizeof(_DB_PMT_)); } for (i =0 ; i < DB_TVCT_MAX; i++) { if (db_tvct[i].rf != nRF) continue; memset(&db_tvct[i], 0, sizeof(_DB_TVCT_)); } for (i =0 ; i < DB_TVCT_SUB_MAX; i++) { if (db_tvct_sub[i].rf != nRF) continue; memset(&db_tvct_sub[i], 0, sizeof(_DB_TVCT_SUB_)); } #if CVCT_SUPPORT for (i =0 ; i < DB_CVCT_MAX; i++) { if (db_cvct[i].rf != nRF) continue; memset(&db_cvct[i], 0, sizeof(_DB_CVCT_)); } for (i =0 ; i < DB_CVCT_SUB_MAX; i++) { if (db_cvct_sub[i].rf != nRF) continue; memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_)); } #endif CT_ChMapUpdate(); DBLock(false); // CDB db; NewCDB(&db); // db.Query(&db, "delete from eit where rf=%d", nRF); // db.Query(&db, "delete from eit_sub where rf=%d", nRF); // db.Query(&db, "delete from ett where rf=%d", nRF); // db.Query(&db, "delete from pat where rf=%d", nRF); // db.Query(&db, "delete from pmt where rf=%d", nRF); //// db.Query("delete from signal where rf=%d", nRF); // db.Query(&db, "delete from tvct where rf=%d", nRF); // db.Query(&db, "delete from tvct_sub where rf=%d", nRF); // db.Query(&db, "delete from cvct where rf=%d", nRF); // db.Query(&db, "delete from cvct_sub where rf=%d", nRF); // db.Query(&db, "delete from channel_db where rf=%d", nRF); // db.Query(&db, "delete from channel_updn where rf=%d", nRF); // DeleteCDB(&db); } #if 0 ____CHANNEL_TASK___() #endif static int gMsgQ = 0; static int gSIMsgQ = 0; typedef struct { DS_U8 Cmd; DHL_MODULATION_MODE demod; DS_U8 RF; DS_U16 program_number; } CT_Msg; #define CMD_NULL 0 #define CMD_TUNE 1 #define CMD_SCAN 2 #define CMD_RF_UPDATE 3 #define CMD_CVT 4 #define CMD_OTC 5 #define CMD_OTC_STOP 6 #define CMD_STOP 7 #define CMD_CLOSE 8 char* CT_GetMsgName(DS_U8 Cmd) { static char strText[32]; sprintf(strText, "Unknown"); switch (Cmd) { case CT_RECEIVE_PAT:sprintf(strText, "CT_RECEIVE_PAT"); break; case CT_RECEIVE_PMT:sprintf(strText, "CT_RECEIVE_PMT"); break; #if EPG_SUPPORT case CT_RECEIVE_MGT:sprintf(strText, "CT_RECEIVE_MGT"); break; #endif case CT_CHMAP_UPDATE:sprintf(strText, "CT_CHMAP_UPDATE"); break; case CT_SIGNAL_INFO:sprintf(strText, "CT_SIGNAL_INFO"); break; case CT_AV_START:sprintf(strText, "CT_AV_START"); break; case CT_SCAN_PSIP_WAIT:sprintf(strText, "CT_SCAN_PSIP_WAIT"); break; case CT_SCAN_LOCK_WAIT:sprintf(strText, "CT_SCAN_LOCK_WAIT"); break; case CT_TUNE_START:sprintf(strText, "CT_TUNE_START"); break; case CT_SCAN_START:sprintf(strText, "CT_SCAN_START"); break; case CT_STOPPED:sprintf(strText, "CT_STOPPED"); break; case CT_RECEIVE_PMT_CC:sprintf(strText, "CT_RECEIVE_PMT_CC"); break; case CT_RECEIVE_PMT_AUDIO:sprintf(strText, "CT_RECEIVE_PMT_AUDIO"); break; } return strText; } static jst_callback g_callback = 0; static void CT_CallBack(DS_U8 Cmd /*= 0*/, DS_U32 p1 /*= 0*/, DS_U32 p2 /*= 0*/, DS_U32 p3 /*= 0*/, DS_U32 p4 /*= 0*/, DS_U32 p5 /*= 0*/, DS_U32 p6 /*= 0*/) { ////if (0) DST_Printf("Cmd = %s(%d) %d %d %d\n", CT_GetMsgName(Cmd), Cmd, p1, p2, p3); if (g_callback) g_callback(Cmd, p1, p2, p3, p4, p5, p6); } static void DST_FreeAtscTable(void *tablePtrPtr) { if (tablePtrPtr == NULL || *(void **) tablePtrPtr == NULL) return; DHL_PSI_FreeMpegSection(*(void **) tablePtrPtr); *(void **) tablePtrPtr = NULL; } typedef struct { DS_U32 RF; DHL_MODULATION_MODE demod; DS_U32 nRequestID; DS_U32 *SI; DS_U32 CRC32; } CT_SI_Msg; typedef struct { DS_U16 pid; DS_U8 type; bool bKorean; bool bVI; } MTS; static int CT_DB_GetAudioPidSub(MTS *mts, int mts_count) { // for (int i = 0; i < mts_count; i++) // { // if (0) DST_Printf("mts[%d].bVI = %d mts[%d].bKorean = %d\n", i, mts[i].bVI, i, mts[i].bKorean); // } int i; // È­¸éÇØ¼³¹æ¼Û + Çѱ¹¾î if (DST_EEPROM_GetVI() == 1 && DST_EEPROM_GetAudioPref() == 0) // È­¸éÇØ¼³¹æ¼Û { // È­¸éÇØ¼³¹æ¼ÛÀ̸鼭 Çѱ¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bVI == true && mts[i].bKorean == true) return i; // ù¹øÂ° Çѱ¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == true) return i; // ù¹øÀç Æ®·¢ return 0; } // È­¸éÇØ¼³¹æ¼Û + ¿Ü±¹¾î if (DST_EEPROM_GetVI() == 1 && DST_EEPROM_GetAudioPref() == 1) // È­¸éÇØ¼³¹æ¼Û { // È­¸éÇØ¼³¹æ¼ÛÀ̸鼭 ¿Ü±¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bVI == true && mts[i].bKorean == false) return i; // ù¹øÂ° ¿Ü±¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == false) return i; // µÎ¹øÀç Æ®·¢ return 1; } // È­¸éÇØ¼³ ¹æ¼Û(x) + Çѱ¹¾î if (DST_EEPROM_GetAudioPref() == 0) // È­¸éÇØ¼³¹æ¼Û { // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ Çѱ¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == true) return i; // ù¹øÂ° Çѱ¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == true) return i; // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ ¿Ü±¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == false) return i; // ù¹øÀç Æ®·¢ return 0; } // È­¸éÇØ¼³ ¹æ¼Û(x) + ¿Ü±¹¾î // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ ¿Ü±¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == false) return i; // ù¹øÂ° ¿Ü±¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == false) return i; // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ Çѱ¹¾î for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == true) return i; // µÎ¹øÀç Æ®·¢ return 1; } // ÀÔ·ÂµÈ ¹®ÀÚ¿­ÀÌ "kor"ÀÎÁö °Ë»çÇÑ´Ù. // -1 unknown 0: ¿Ü±¹¾î 1: Çѱ¹¾î static int isKOR(char* strText) { if (strText == 0) return -1; int nLen = strlen(strText); if (nLen != 3) return -1; int i; for ( i= 0; i < nLen; i++) if (strText[i] >='A' && strText[i] <= 'Z') strText[i] -= ('A'-'a'); // tolower return (strcmp(strText, "kor") == 0) ? 1 : 0; } int CT_GetAudioCount(DS_U8 RF, DS_U16 program_number) { int pmt_audio_count = 0; int i; DBLock(true); for ( i = 0; i < MAX_PMT_AUDIO_TABLE_COUNT; i++) { if (pmt_audio_table[i].program_number == 0) continue; if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == program_number) pmt_audio_count++; } DBLock(false); return pmt_audio_count; } static bool g_ReceivePMTAudio = false; void CT_DB_GetAudioPid(DS_U8 RF, DS_U16 program_number, DS_U16* pid, DS_U8* type) { static DS_U32 old_RF = 0; static DS_U16 old_program_number = 0; static DS_U16 old_pid = 0; static DS_U8 old_type = 0; if (program_number == 0) return; DBLock(true); if (g_ReceivePMTAudio == true || DST_g_AudioSettingChanged == true || old_RF != RF || old_program_number != program_number) { DST_g_AudioSettingChanged = false; int pmt_audio_count = 0; typedef struct { int pid; int type; } PMT_AUDIO; PMT_AUDIO pmt_audio[32]; memset(pmt_audio, 0, sizeof(pmt_audio)); int i; for ( i = 0; i < MAX_PMT_AUDIO_TABLE_COUNT; i++) { if (pmt_audio_table[i].program_number == 0) continue; if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == program_number) { pmt_audio[pmt_audio_count].pid = pmt_audio_table[i].pid; pmt_audio[pmt_audio_count].type = pmt_audio_table[i].type; pmt_audio_count++; } if (pmt_audio_count == 32) break; } if (pmt_audio_count < 1) { *pid = 0; *type = 0; } else { if (pmt_audio_count == 1) { *pid = pmt_audio[0].pid; *type = pmt_audio[0].type; } else { int mts_count = pmt_audio_count; MTS *mts = (MTS*)DST_OS_Malloc(sizeof(MTS)*mts_count); int i; for ( i = 0; i < mts_count; i++) { mts[i].pid = pmt_audio[i].pid; mts[i].type = pmt_audio[i].type; mts[i].bKorean = true; mts[i].bVI = false; int nKorean[3] = {-1, -1, -1}; // unknown // AC-3 Audio Descriptor °¡ ¿ì¼± ¼øÀ§°¡ ³ô´Ù int j; for ( j = 0; j < MAX_PMT_ISO_TABLE_COUNT; j++) { if (pmt_iso_table[j].rf == (int)RF && pmt_iso_table[j].program_number == program_number && pmt_iso_table[j].pid == mts[i].pid) { DS_U8 audio_type = pmt_iso_table[j].type; mts[i].bVI = (audio_type == 0x03); nKorean[0] = isKOR(pmt_iso_table[j].lang); break; } } for ( j = 0; j < MAX_PMT_AC3_TABLE_COUNT; j++) { if (pmt_ac3_table[j].rf == (int)RF && pmt_ac3_table[j].program_number == program_number && pmt_ac3_table[j].pid == mts[i].pid) { DS_U8 bsmod = pmt_ac3_table[j].bsmod; DS_U8 full_svc = pmt_ac3_table[j].full_svc; DS_U8 langcod = pmt_ac3_table[j].langcod; mts[i].bVI = (bsmod == 0x02 && full_svc == 0x01); nKorean[1] = (langcod == 0xFF) ? -1 : (langcod == 0x65) ? 1 : 0; nKorean[2] = isKOR(pmt_ac3_table[j].language); break; } } // if (0) DST_Printf("nKorean[0] = %d nKorean[1] = %d nKorean[2] = %d\n", nKorean[0], nKorean[1], nKorean[2]); if (nKorean[0] == 0 || nKorean[1] == 0 || nKorean[2] == 0) mts[i].bKorean = false; // µÑ ÁßÇϳª ¿Ü±¹¾îÀÎ °æ¿ì ¿Ü±¹¾î if (nKorean[0] == 1 || nKorean[1] == 1 || nKorean[2] == 1) mts[i].bKorean = true; // µÑ Áß Çϳª Çѱ¹¾îÀÎ °æ¿ì Çѱ¹¾î //isoÁ¤º¸ ac3Á¤º¸ °áÁ¤µÈ¾ð¾î //¾Ë¼ö¾øÀ½ ¾Ë¼ö¾øÀ½ Çѱ¹¾î //¾Ë¼ö¾øÀ½ ¿Ü±¹¾î ¿Ü±¹¾î //¾Ë¼ö¾øÀ½ Çѱ¹¾î Çѱ¹¾î //¿Ü±¹¾î ¾Ë¼ö¾øÀ½ ¿Ü±¹¾î //¿Ü±¹¾î ¿Ü±¹¾î ¿Ü±¹¾î //¿Ü±¹¾î Çѱ¹¾î Çѱ¹¾î //Çѱ¹¾î ¾Ë¼ö¾øÀ½ Çѱ¹¾î //Çѱ¹¾î ¿Ü±¹¾î Çѱ¹¾î //Çѱ¹¾î Çѱ¹¾î Çѱ¹¾î } int nPos = CT_DB_GetAudioPidSub(mts, mts_count); *pid = mts[nPos].pid; *type = mts[nPos].type; DST_OS_Free(&mts); } } g_ReceivePMTAudio = false; old_RF = RF; old_program_number = program_number; old_pid = *pid; old_type = *type; } else { *pid = old_pid; *type = old_type; } DBLock(false); } //static void CT_DB_GetCCPid(DS_U8 RF, DS_U16 sID,DS_U16 pid[8]) //{ // CDB db; // db.GetTable("select pid from pmt_cc where rf=%d and program_number=%d", RF, sID); // memset(pid, 0, sizeof(DS_U16)*8); // for (int i = 0; i < db.GetRow(); i++) pid[i] = dst_atoi(db.GetResult(i+1)); //} void CT_DB_GetVideoPid(DS_U8 RF, DS_U16 sID,DS_U16* pcr, DS_U16* pid, DS_U8* type) { //CDB db; NewCDB(&db); //db.GetTable(&db, "select pcr_pid, video_pid, video_type from pmt where rf=%d and program_number=%d", RF, sID); int i; DBLock(true); for (i=0; i < DB_PMT_MAX; i++) { if (db_pmt[i].program_number == 0) continue; if (db_pmt[i].rf != RF) continue; if (db_pmt[i].program_number != sID) continue; if (pcr) *pcr = db_pmt[i].pcr_pid; if (pid) *pid = db_pmt[i].video_pid; if (type) *type = db_pmt[i].video_type; DBLock(false); return; } DBLock(false); } #if 0 // Newcon3Kr¿¡¼­ »ç¿ë ¾ÈÇÔ #define MAX_CRC_COUNT 400 class CheckCRC32 { private: int nPos; DS_U32 CRC32[MAX_CRC_COUNT]; public: CheckCRC32() { memset(CRC32, 0, sizeof(CRC32)); nPos = 0; } void Add(DS_U32 crc32) { for (int i = 0; i < MAX_CRC_COUNT; i++) if (CRC32[i] == crc32) return; CRC32[nPos] = crc32; nPos++; if (nPos >= MAX_CRC_COUNT) nPos = 0; } bool IsDuplicate(DS_U32 crc32) { for (int i = 0; i < MAX_CRC_COUNT; i++) if (CRC32[i] == crc32) return true; return false; } // CRC LIST¿¡ ¾ø´Â CRC´Â Áö¿î´Ù. void Clear(DS_U32 *crclist, int nCount) { for (int i = 0; i < MAX_CRC_COUNT; i++) { if (CRC32[i] == 0) continue; bool bFind = false; for (int j=0; j tables_defined = %d\n", mgt->tables_defined); int i; for( i = 0 ; i< mgt->tables_defined ; i++) { if (0) DST_Printf("mgt->table[%d].table_type = 0x%X table_type_PID = 0x%X\n", i, mgt->table[i].table_type, mgt->table[i].table_type_PID); if (mgt->table[i].table_type >= 0x100 && mgt->table[i].table_type <0x100 + MAX_EIT_COUNT) { T(); int pos = mgt->table[i].table_type - 0x100; if (eit_pid[pos] == mgt->table[i].table_type_PID) continue; eit_pid[pos] = mgt->table[i].table_type_PID; //DHL_SI_MonitorStop(&hEIT[pos]); //hEIT[pos] = DHL_SI_MonitorEIT(RF, POS_EIT+pos, eit_pid[pos]); } if (mgt->table[i].table_type >= 0x200 && mgt->table[i].table_type <0x200 + MAX_EIT_COUNT) { T(); int pos = mgt->table[i].table_type - 0x200; if (ett_pid[pos] == mgt->table[i].table_type_PID) continue; ett_pid[pos] = mgt->table[i].table_type_PID; //DHL_SI_MonitorStop(&hETT[pos]); //hETT[pos] = DHL_SI_MonitorETT(RF, POS_ETT+pos, ett_pid[pos]); } } CT_CallBack(CT_RECEIVE_MGT, RF, 0,0,0,0,0); } if (msg.nRequestID >= POS_EIT && msg.nRequestID < POS_EIT+MAX_EIT_COUNT) { EIT *eit = (EIT*)msg.SI; if (eit->source_id == source_id) { CT_ChMapUpdateEIT(RF, eit, msg.nRequestID - POS_EIT, msg.CRC32); CT_CallBack(CT_RECEIVE_EIT, RF, 0,0,0,0,0); } } if (msg.nRequestID >= POS_ETT && msg.nRequestID < POS_ETT+MAX_EIT_COUNT) { ETT *ett = (ETT*)msg.SI; if ((ett->ETM_id >> 16) == source_id) { CT_ChMapUpdateETT(RF, ett, msg.CRC32); CT_CallBack(CT_RECEIVE_ETT, RF, 0,0,0,0,0); } } #endif if (msg.nRequestID == POS_PAT) { MPEG_PAT *pat = (MPEG_PAT*)msg.SI; CT_ChMapUpdatePAT(RF, pat, msg.CRC32); int nPos = 0; int i; for ( i = 0; i < MAX_PMT_COUNT; i++) { if (hPMT[i]) DHL_SI_MonitorStop(&hPMT[i]); } for ( i = 0; i < pat->numPrograms; i++) { if (pat->programs[i].program_map_PID == 0) continue; if (pat->programs[i].program_map_PID == 0x1FFF) continue; hPMT[nPos] = DHL_SI_MonitorPMT(RF, POS_PMT+nPos, pat->programs[i].program_map_PID, pat->programs[i].program_number); nPos++; if (nPos >= MAX_PMT_COUNT) break; } CT_CallBack(CT_RECEIVE_PAT, RF, 0,0,0,0,0); } if (msg.nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT) { bReceivePMT = true; MPEG_PMT *pmt = (MPEG_PMT*)msg.SI; if (CT_ChMapUpdatePMT(RF, pmt, msg.nRequestID - POS_PMT+1, msg.CRC32)) { CT_ChMapUpdate(); } CT_CallBack(CT_RECEIVE_PMT, RF, pmt->program_number, 0,0,0,0); g_ReceivePMTAudio = true; CT_CallBack(CT_RECEIVE_PMT, RF, 0,0,0,0,0); } } DST_FreeAtscTable(&msg.SI); // ¸Þ¸ð¸® ÇØÁ¦´Â ¿©±â¿¡¼­ } // while { // CC µð½ºÅ©¸³ÅÍ ¸ð´ÏÅ͸µ static DS_U32 old_RF = 0; static DS_U16 old_program_number = 0; if (old_RF != RF || old_program_number != program_number || g_bReceiveCCDescriptor == true) { old_RF = RF; old_program_number = program_number; g_bReceiveCCDescriptor = false; bool bFind = false; int i; for ( i=0; i < MAX_PMT_CC_TABLE_COUNT; i++) { if (pmt_cc_table[i].rf == (int)RF && pmt_cc_table[i].program_number == program_number && pmt_cc_table[i].cc_type > 0 && pmt_cc_table[i].cc_id == 1) { DST_g_CC_bCCKorean = (strcmp(pmt_cc_table[i].language, "kor") != 0 && strcmp(pmt_cc_table[i].language, "KOR") != 0) ? false : true; DST_g_CC_bWideScreen = pmt_cc_table[i].wide_aspect_ratio ? true : false; DST_g_CC_bUnicode = pmt_cc_table[i].korean_code ? true : false; bFind = true; break; } } if (bFind == false) { DST_g_CC_bCCKorean = true; DST_g_CC_bWideScreen = true; DST_g_CC_bUnicode = false; } } } #if EPG_SUPPORT { // EIT ETT ¸ð´ÏÅ͸µ static DS_U8 old_RF = 0; static DS_U16 old_source_id = 0; if (old_RF != RF || old_source_id != source_id || g_bReceiveMGT == true) { old_RF = RF; old_source_id = source_id; int i; for ( i = 0; i < MAX_EIT_COUNT; i++) { if (hEIT[i]) DHL_SI_MonitorStop(&hEIT[i]); if (hETT[i]) DHL_SI_MonitorStop(&hETT[i]); } for ( i = 0; i < MAX_EIT_COUNT; i++) { if (eit_pid[i]) hEIT[i] = DHL_SI_MonitorEIT(RF, POS_EIT+i, eit_pid[i], source_id); if (ett_pid[i]) hETT[i] = DHL_SI_MonitorETT(RF, POS_ETT+i, ett_pid[i], source_id); } } } #endif if (bReceivePMT) // PMT ¹ÞÀº ÈÄ ´Ù¸¥ ¸ð´ÏÅ͸µ ½ÃÀÛÇÏÀÚ { #if EPG_SUPPORT if (hMGT== 0) hMGT = DHL_SI_MonitorMGT(RF, POS_MGT); #endif #if CVCT_SUPPORT if (hCVCT== 0) hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT); #endif if (hSTT == 0) hSTT = DHL_SI_MonitorSTT(RF, POS_STT); if (hTVCT == 0) hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT); } } else // bStart == false { CT_TunePSIP(0, DHL_MODULATION_8VSB, 0, 0, false); bStart = true; hPAT = DHL_SI_MonitorPAT(RF, POS_PAT); // PMT¸¦ »¡¸® ¹Þ±â À§ÇØ ´Ù¸¥ SI´Â ´Ê°Ô ¹Þ´Â´Ù. } } else { if (bStart) { DHL_SI_MonitorStop(&hTVCT); // DHL_SI_MonitorStop(&hCVCT); DHL_SI_MonitorStop(&hSTT); #if EPG_SUPPORT DHL_SI_MonitorStop(&hMGT); #endif int i; #if EPG_SUPPORT for ( i = 0; i < MAX_EIT_COUNT; i++) { DHL_SI_MonitorStop(&hEIT[i]); eit_pid[i] = 0; DHL_SI_MonitorStop(&hETT[i]); ett_pid[i] = 0; } #endif DHL_SI_MonitorStop(&hPAT); for ( i = 0; i < MAX_PMT_COUNT; i++) { DHL_SI_MonitorStop(&hPMT[i]); } CT_SI_Msg msg; DS_U32 retLen = 0; while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError) { if (0) DST_Printf("Remove msg.nRequestID == %d\n", (int)msg.nRequestID); DST_FreeAtscTable(&msg.SI); } bStart = false; bReceivePMT = false; } } } static void CT_VideoAudio(DS_U16 pcr /*= 0*/, DS_U16 vpid /*= 0*/, DS_U8 vtype /*= 0*/, DS_U16 apid /*= 0*/, DS_U8 atype /*= 0*/) { static DS_U16 _pcr = 0; static DS_U16 _vpid = 0; static DS_U8 _vtype = 0; static DS_U16 _apid = 0; static DS_U8 _atype = 0; if (pcr == _pcr && vpid == _vpid && vtype == _vtype && apid == _apid && atype == _atype) return; if (vpid != _vpid) { if (vpid) { DHL_VIDEO_TYPE VidStreamType = DHL_VIDEO_NONE; switch (vtype) // ABNT NBR 15602-3:2007 Table 5 ? Strem_type { case 0x01: VidStreamType = DHL_VIDEO_MPEG1; break; case 0x02: VidStreamType = DHL_VIDEO_MPEG2; break; case 0x1B: VidStreamType = DHL_VIDEO_MPEG4; break; }; if (DHL_VID_Start(vpid, pcr, VidStreamType) != 0) return; DST_g_LastVideoStartTime = DST_OS_GetTickCount(); _apid = 0; // ºñµð¿À º¯°æ ½Ã ¿Àµð¿Àµµ ´Ù½Ã ½ÃÀÛÇϱâ À§Çؼ­ ÀÌÀü ¿Àµð¿À »óŸ¦ Áö¿î´Ù. } else { // CT_ChannelChangeVideoMute(true); DHL_VID_Stop(); DST_g_LastVideoStartTime = 0; } } if (apid != _apid) { if (apid) { DHL_AUDIO_TYPE AudStreamType = DHL_AUDIO_NONE; switch (atype) // ABNT NBR 15602-3:2007 Table 5 ? Strem_type { case 0x03: AudStreamType = DHL_AUDIO_MPEG1; break; case 0x04: AudStreamType = DHL_AUDIO_MPEG2; break; case 0x0F: AudStreamType = DHL_AUDIO_AAC_ADTS; break; case 0x11: AudStreamType = DHL_AUDIO_AAC_LATM; break; case 0x81: AudStreamType = DHL_AUDIO_AC3; break; }; DHL_AUD_Start(apid, pcr == 0 ? 0x1FFF : pcr, AudStreamType); CT_ChannelChangeAudioMute(false); DST_g_LastAudioStartTime = DST_OS_GetTickCount(); } else { CT_ChannelChangeAudioMute(true); DHL_AUD_Stop(); DST_g_LastAudioStartTime = 0; } } _pcr = pcr; _vpid = vpid; _vtype = vtype; _apid = apid; _atype = atype; } static void CT_AV(DS_U8 RF /*= 0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, DS_U16 program_number /*= 0*/, DS_U16 source_id /*= 0*/, bool bOn /*= false*/) { if (bOn) { // ½ÅÈ£ Á¤º¸ bool bLock = false; int ss = 0, power = 0, snr = 0; DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr); CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0); // ¼Ò½º¾ÆÀ̵𿡠µû¶ó AV¸¦ ½ÃÀÛÇÑ´Ù. DS_U16 PcrPid = 0; DS_U16 VideoPid = 0; DS_U8 VideoType = 0; DS_U16 AudioPid = 0; DS_U8 AudioType = 0; CT_DB_GetVideoPid(RF, program_number, &PcrPid, &VideoPid, &VideoType); // if (0) DST_Printf("VideoPid = %d\n", VideoPid); CT_DB_GetAudioPid(RF, program_number, &AudioPid, &AudioType); //if (0) DST_Printf("AudioPid = %d\n", AudioPid); CT_VideoAudio(PcrPid, VideoPid, VideoType, AudioPid, AudioType); CT_CallBack(CT_AV_START, RF, program_number, source_id, 0,0,0); CT_CallBack(CT_AV_INFO, RF, PcrPid, VideoPid, AudioPid, VideoType, AudioType); // CC ¸ð´ÏÅ͸µÀ» ½ÃÀÛÇÑ´Ù. // AV »óÅ Á¤º¸ Äݹé CT_CallBack(CT_SIGNAL, RF, program_number, VideoPid ? DHL_VID_Alive() : 0, AudioPid ? DHL_AUD_Alive() : 0, 0,0); CT_CallBack(CT_AUDIO_MODE, DHL_AUD_GetMode(),0,0,0,0, 0); CT_TunePSIP(RF, demod, program_number, source_id, bOn); } else { CT_TunePSIP(0, DHL_MODULATION_8VSB, 0, 0, false); // PSIP ¸ð´ÏÅ͸µ ÁßÁö CT_VideoAudio(0,0,0,0,0); } } static void CT_Tune(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, DS_U16 program_number/*=0*/, DS_U16 source_id /*= 0*/, bool bOn/*= false*/) { static bool bStart = false; static DS_U8 CurrentRF = 0; static DHL_MODULATION_MODE CurrentDemod = DHL_MODULATION_NULL; if (bOn) { if (bStart == false || CurrentRF != RF || CurrentDemod != demod) { CT_AV(0, DHL_MODULATION_8VSB, 0, 0, false); DHL_TUN_Start(RF, demod); DST_g_LastTuneTime = DST_OS_GetTickCount(); CurrentRF = RF; CurrentDemod = demod; bStart = true; } CT_AV(RF, demod, program_number, source_id, bOn); } else { CT_AV(0, DHL_MODULATION_8VSB, 0,0,false); if (bStart) { DST_g_LastTuneTime = 0; DHL_TUN_Stop(); bStart = false; } } } typedef struct { DS_U8 vendor_id[3]; DS_U8 hardware_version_id[4]; DS_U8 software_version_id[4]; DS_U8 so_id[2]; DS_U8 download_type; /* 4bits */ DS_U8 download_command; /* 4bits */ DS_U16 frequency_vector; /* 16bits */ DS_U8 modulation_type; DS_U16 PID; } AirCodeCVT; static bool DST_SCTESI_ParseAirCodeCVT(DS_U8 *p, AirCodeCVT *cvt) { if (p == 0 || cvt == 0) return false; if (p[0] != 0x90) return false; // invalid table memset(cvt, 0, sizeof(AirCodeCVT)); DS_U8 number_of_descriptor = p[8]; int nPos = 9; if (0) DST_Printf("number_of_descriptor = %d", number_of_descriptor); int i; for ( i = 0; i < number_of_descriptor; i++) { DS_U8 tag = p[nPos]; DS_U8 length = p[nPos+1]; if (0) DST_Printf("tag = %d\n", tag); if (0) DST_Printf("length = %d\n", length); switch (tag) { case 0: // vendor_id // T(); if (length == 3) memcpy(cvt->vendor_id, &p[nPos+2], length); break; case 1: // hardware_version_id // T(); if (length == 4) memcpy(cvt->hardware_version_id, &p[nPos+2], length); break; case 2: // softeware_version_id // T(); if (length == 4) memcpy(cvt->software_version_id, &p[nPos+2], length); break; case 0x80: // T(); if (length == 2) memcpy(cvt->so_id, &p[nPos+2], length); break; } nPos = nPos + length + 2; } cvt->download_type = (p[nPos]&0xF0) >> 4; cvt->download_command = (p[nPos]&0x0F); cvt->frequency_vector = p[nPos+1]*256 + p[nPos+2]; cvt->modulation_type = p[nPos+3]; cvt->PID = (p[nPos+4]&0x1F)*256 + p[nPos+5]; return true; } static void CT_SI_Proc(DS_U32 RF, DS_U32 nRequestID, DS_U8** buff, DS_U32 nBuffLength) { if (0) DST_Printf("%s | RF = %d | nRequestID = %d %s\n", __func__, (int)RF, (int)nRequestID, GetSiName(nRequestID)); CT_SI_Msg msg; msg.RF = RF; msg.nRequestID = nRequestID; msg.SI = 0; msg.CRC32 = CalcCRC(buff[0]); #if 1 if (msg.CRC32 != DST_CRC32(buff[0], (*(buff[0]+1)&0x0F) * 256 + *(buff[0]+2) - 1)) { DST_Printf("%s|Invalid CRC nRequestID =%d %s\n", __func__, nRequestID, GetSiName(nRequestID)); return; } #endif if (nRequestID == POS_TVCT) { if (DHL_PSI_ParseTVCT(buff, (TVCT **)&msg.SI)) if (0) DST_Printf("%s|%d|TVCT Parse Error\n", __func__, __LINE__); } #if CVCT_SUPPORT if (nRequestID == POS_CVCT) { if (DHL_PSI_ParseCVCT(buff, (CVCT **)&msg.SI)) if (0) DST_Printf("%s|%d|CVCT Parse Error\n", __func__, __LINE__); } #endif if (nRequestID == POS_STT) { DS_U8* p = buff[0]; CT_CallBack(CT_RECEIVE_STT, RF, p[9] * 0x1000000 + p[10] * 0x10000 + p[11] * 0x100 + p[12] , p[13], DST_OS_GetTickCount(), 0,0); } #if EPG_SUPPORT if (nRequestID == POS_MGT) { if (DHL_PSI_ParseMGTSection(buff[0], (MGT **)&msg.SI)) if (0) DST_Printf("%s|%d|MGT Parse Error\n", __func__, __LINE__); } if (nRequestID >= POS_EIT && nRequestID < POS_EIT+MAX_EIT_COUNT) { if (DHL_PSI_ParseEIT(buff, (EIT **)&msg.SI)) if (0) DST_Printf("%s|%d|EIT Parse Error\n", __func__, __LINE__); } if (nRequestID >= POS_ETT && nRequestID < POS_ETT+MAX_EIT_COUNT) { if (DHL_PSI_ParseETTSection(buff[0], (ETT **)&msg.SI)) if (0) DST_Printf("%s|%d|ETT Parse Error\n", __func__, __LINE__); } #endif if (nRequestID == POS_PAT) { if (DHL_PSI_ParsePAT(buff, (MPEG_PAT **)&msg.SI)) if (0) DST_Printf("%s|%d|PAT Parse Error\n", __func__, __LINE__); } if (nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT) { if (DHL_PSI_ParsePMT(buff[0], (MPEG_PMT **)&msg.SI)) if (0) DST_Printf("%s|%d|PMT Parse Error\n", __func__, __LINE__); } if (nRequestID == POS_RFUPDATE) { CT_CallBack(CT_RECEIVE_RF_UPDATE, RF, (DS_U32)buff[0],0,0,0,0); } if (nRequestID == POS_CVT) // CVT { // DST_g_ReceiveCVT++; // CMB´Â DDBµ¥ÀÌÅÍ¿¡ ¹Ýº¹µÇ´Â CVT ½Ç·Á¿Â´Ù. // CVT ÆÄÀÏÀ» °ËÃâÇÏ¿© 0x90À¸·Î ½ÃÀÛÇÏ´Â Å×À̺í·Î º¯È¯ÇÑ´Ù. // CVT°¡ ¿¬¼ÓÇØ¼­ ¿À±â ¶§¹®¿¡ ¼ö½ÅÇÑ CVT´Â ÀúÀåÇÏ¿© µÎ¾î Áߺ¹ 󸮸¦ ¹æÁöÇÑ´Ù. static DS_U8 received_cvt[300]; DS_U8 cvt_new[300]; DS_U8* p = buff[0]; DS_U16 section_length = (p[1] & 0x0F) * 256 + p[2]; bool bFind = false; int i; for ( i = 26; i < section_length - 32; i++) // CVT Å×ÀÌºí ¾ÕÀÇ 26¹ÙÀÌÆ®´Â ´õ¹Ì CVT Å×À̺íÀÇ ÃÖ¼Ò Å©±â´Â 32¹ÙÀÌÆ® { if (p[i] == 0xD9 && p[i+1] == 0x30 && p[i+3] == 0x9F && p[i+4] == 0x9C && p[i+5] == 0x02) { if (i+p[i+6] > section_length) return; // ÀÔ·ÂµÈ µ¥ÀÌÅͱæÀ̺¸´Ù Å« °æ¿ì ¿¡·¯Ã³¸® memset(cvt_new, 0, 300); cvt_new[0] = 0x90; memcpy(&cvt_new[1], &p[i], p[i+6] + 3); if (!memcmp(cvt_new, received_cvt, 300)) return; // ÀÌ¹Ì ¹ÞÀ½ bFind = true; break; } } if (bFind == false) { return; } static bool bReceiveValidCVT = false; if (bReceiveValidCVT == true) return; AirCodeCVT cvt; memset(&cvt, 0, sizeof(AirCodeCVT)); if (DST_SCTESI_ParseAirCodeCVT(cvt_new, &cvt) == false) return; #if 1 if (1) DST_Printf("============================================\n"); if (1) DST_Printf("Request ID = POS_CVT\n"); if (1) DST_Printf("vendor_id %02X %02X %02X\n", cvt.vendor_id[0], cvt.vendor_id[1], cvt.vendor_id[2]); if (1) DST_Printf("hardware_version_id %02X %02X %02X %02X\n", cvt.hardware_version_id[0], cvt.hardware_version_id[1], cvt.hardware_version_id[2], cvt.hardware_version_id[3]); if (1) DST_Printf("software_version_id %02X %02X %02X %02X\n", cvt.software_version_id[0], cvt.software_version_id[1], cvt.software_version_id[2], cvt.software_version_id[3]); if (1) DST_Printf("so_id %02X %02X\n", cvt.so_id[0], cvt.so_id[1]); if (1) DST_Printf("download_type %d\n", cvt.download_type); if (1) DST_Printf("download_command %d\n", cvt.download_command); if (1) DST_Printf("frequency_vector %d\n", cvt.frequency_vector); if (1) DST_Printf("modulation_type %d\n", cvt.modulation_type); if (1) DST_Printf("PID 0x%X\n", cvt.PID); if (1) DST_Printf("============================================\n"); #endif // °¢ ÇÊµå °ªÀÇ À¯È¿¼º °Ë»ç if (cvt.vendor_id[0] != 'D') return; if (cvt.vendor_id[1] != 'S') return; if (cvt.vendor_id[2] != 'T') return; if (cvt.hardware_version_id[0] != 'N') return; if (cvt.hardware_version_id[1] != '3') return; if (cvt.hardware_version_id[2] != 'K') return; if (cvt.hardware_version_id[3] != 'R') return; // if (cvt.so_id[0] != DST_g_SO_ID/256) return; // if (cvt.so_id[1] != DST_g_SO_ID%256) return; // º¥´õ¾ÆÀ̵ð¿Í H/W ¹öÀüÀÌ ÀÏÄ¡ÇÏÁö ¾Ê´Â Á¤º¸°¡ °°Àº PID·Î ¿Ã °¡´É¼º ´ëºñÇÏ¿© ¹é¾÷ À§Ä¡´Â H/W ¹öÀü üũ ÀÌÈÄ·Î memcpy(received_cvt, cvt_new, 300); // »õ·Î ¹ÞÀº µ¥ÀÌÅ͸¦ ¹é¾÷ int major = 0, minor = DST_GetAppShortVersionNumber(); if (1) DST_Printf("major = %d minor = %d\n", major, minor); int new_major = cvt.software_version_id[0]*256+cvt.software_version_id[1]; int new_minor = cvt.software_version_id[2]*256+cvt.software_version_id[3]; if (1) DST_Printf("new_major = %d new_minor = %d\n", new_major, new_minor); if ((major * 0x10000 + minor) >= (new_major * 0x10000 + new_minor)) { if (1) DST_Printf("Old or Same version. ignore it.\n"); return; } if (cvt.download_command > 2) { if (1) DST_Printf("download_command invalid(%d)\n", cvt.download_command); return; } if (cvt.frequency_vector == 0) { if (1) DST_Printf("frequency_vector invalid(%d)\n", cvt.frequency_vector); return; } if (cvt.modulation_type < 1 || cvt.modulation_type > 2) { if (1) DST_Printf("modulation_type invalid(%d)\n", cvt.modulation_type); return; } if (cvt.PID == 0) { if (1) DST_Printf("PID invalid(%d)\n", cvt.PID); return; } bReceiveValidCVT = true; #if 1 switch (cvt.download_command) { case 0: if (1) DST_Printf("Download Now\n"); break; case 1: if (1) DST_Printf("Deferred Download\n"); break; case 2: if (1) DST_Printf("No Exception\n"); break; } if (1) DST_Printf("OTC RF = %dHz\n", cvt.frequency_vector * 250000); switch (cvt.modulation_type) { case 1: if (1) DST_Printf("64QAM\n"); break; case 2: if (1) DST_Printf("256QAM\n"); break; } #endif SWinEventMsg event; memset(&event, 0, sizeof(SWinEventMsg)); event.cmd = WM_CVT; memcpy(&event.data[0], &cvt.software_version_id[0], 16); event.data32[4] = cvt.download_command; event.data32[5] = cvt.modulation_type; event.data32[6] = cvt.frequency_vector * 250000; event.data32[7] = cvt.PID; DST_SendWindowEvent(event); #ifdef DSTAR DST_g_OTC_Modulation_type = (event.data32[5]==1)?(DHL_MODULATION_64QAM):(DHL_MODULATION_256QAM); DST_g_OTC_RF = event.data32[6]; DST_g_OTC_PID = event.data32[7]; // DST_OTC_Start(); #endif } if (nRequestID == POS_OTC_DII) // OTC_DII { if (1) DST_Printf("################## Request ID = POS_OTC_DII\n"); // DST_OTC_ParseDsmcc(buff[0]); DS_U8 *p = buff[0]; if (p[0] != 0x4B) return; // TABLE ID DS_U16 section_length = ((p[1]&0x0F) * 0x100) + p[2]; if (section_length < 48) return; // SECTION TOO SHORT if (p[10] != 0x10 || p[11] != 0x02) return; // DSMCC_DM_MSG_DII 0x1002 DS_U8 adaptationLength = p[17]; if (section_length < 48 + adaptationLength) return; // SECTION TOO SHORT p += adaptationLength; // adaptationLength ±æÀ̸¸Å­ Æ÷ÀÎÅÍ À̵¿ DS_U16 blockSize = p[24] * 0x100 + p[25]; DS_U32 moduleSz = p[42]* 0x1000000 + p[43]* 0x10000 + p[44]* 0x100 + p[45]; if (1) DST_Printf("blockSize = %d moduleSz = %d\n", blockSize, (int)moduleSz); CT_CallBack(CT_OTC_RECEIVE_DII, moduleSz, blockSize,0,0,0,0); } if (nRequestID == POS_OTC_DDB) // OTC_DDB { //if (0) DST_Printf("############## Request ID = POS_OTC_DDB\n"); //DST_OTC_ParseDsmcc(buff[0]); DS_U8 *p = buff[0]; if (p[0] != 0x4C) return; // TABLE ID //DS_U16 section_length = ((p[1]&0x0F) * 0x100) + p[2]; //if (section_length < 48) return; // SECTION TOO SHORT if (p[10] != 0x10 || p[11] != 0x03) return; // DSMCC_DM_MSG_DDB 0x1003 DS_U8 adaptationLength = p[17]; //if (section_length < 48 + adaptationLength) return; // SECTION TOO SHORT p += adaptationLength; // adaptationLength ±æÀ̸¸Å­ Æ÷ÀÎÅÍ À̵¿ DS_U16 blockSize = p[18] * 0x100 + p[19]; DS_U16 blockNumber = p[24]* 0x100 + p[25]; //if (0) DST_Printf("blockSize = %d blockNumber = %d\n", blockSize-6, blockNumber); CT_CallBack(CT_OTC_RECEIVE_DDB, blockNumber, (DS_U32)&p[26], blockSize-6,0,0,0); } if (msg.SI) DST_OS_SendMessage(gSIMsgQ, (DS_U32 *)&msg, sizeof(CT_SI_Msg)); } // ÇÑ RF¿¡ ´ëÇÑ ¿ÀÅ佺ĵÀÌ ³¡³ª°í ³ª¼­ ´ÙÀ½ ä³Î·Î °¥¶§ ÇöÀç RF¿¡¼­ SI¸¦ ¹Þ¾Ò´ÂÁö ¿©ºÎ¸¦ ÆÇ´ÜÇØ¼­ // ä³Î¸ÊÀ» Áö¿ö¾ß ÇÑ´Ù. static bool g_bRemovedOldChannel = false; // PAT/CVCT/TVCT Áß Çϳª¸¦ ¹ÞÀ¸¸é ÀÌÀü ä³ÎÀ» Áö¿î´Ù. bool CT_ScanFindChannel() { return g_bRemovedOldChannel; } static void CT_ScanPSIP(DS_U8 RF/*=0*/, bool bOn/*=false*/) { static bool bStart = false; static DS_U32 startTick = 0; static DHL_HANDLE hTVCT = 0; #if CVCT_SUPPORT static DHL_HANDLE hCVCT = 0; #endif static DHL_HANDLE hPAT = 0; static DHL_HANDLE hPMT[MAX_PMT_COUNT]; static int remain_pmt_count = 0; if (bOn) { if (bStart) { CT_SI_Msg msg; DS_U32 retLen = 0; while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError) { if (RF == msg.RF) { // PAT/CVCT/TVCT Áß Çϳª¸¦ ¹ÞÀ¸¸é ÀÌÀü ä³ÎÀ» Áö¿î´Ù. if (msg.nRequestID == POS_TVCT || #if CVCT_SUPPORT msg.nRequestID == POS_CVCT || #endif msg.nRequestID == POS_PAT) { if (g_bRemovedOldChannel == false) { // JST_DB_Del(RF); g_bRemovedOldChannel = true; } } if (msg.nRequestID == POS_TVCT) { TVCT *tvct = (TVCT*)msg.SI; if (CT_ChMapUpdateTVCT(RF, tvct, msg.CRC32)) { CT_ChMapUpdate(); } CT_CallBack(CT_SCAN_RECEIVE_TVCT, msg.RF, (DS_U32)tvct,0,0,0,0); } #if CVCT_SUPPORT if (msg.nRequestID == POS_CVCT) { CVCT *cvct = (CVCT*)msg.SI; if (CT_ChMapUpdateCVCT(RF, cvct, msg.CRC32)) { CT_ChMapUpdate(); } CT_CallBack(CT_SCAN_RECEIVE_CVCT, msg.RF, (DS_U32)cvct,0,0,0,0); } #endif if (msg.nRequestID == POS_PAT) { MPEG_PAT *pat = (MPEG_PAT*)msg.SI; if (CT_ChMapUpdatePAT(RF, pat, msg.CRC32)) // PAT°¡ °»½ÅµÇ¾ú´Ù { // VCT°¡ ÀÖ´ø ä³Î¿¡¼­ VCT°¡ ¾ø´Â ä³Î·Î ½ºÆ®¸²ÀÌ º¯°æµÈ °æ¿ì ¹Ý¿µÇϱâ À§ÇÑ ÄÚµå // VCT°¡ ¾ø´Â ä³ÎÀϼö ÀÖÀ¸´Ï VCT Á¤º¸¸¦ Áö¿ì°í »õ·Î ¹Þ¾Æº»´Ù. DHL_SI_MonitorStop(&hTVCT); // DHL_SI_MonitorStop(&hCVCT); // VCT Á¤º¸¸¦ Á¦°ÅÇÑ´Ù { // CDB db; NewCDB(&db); // db.Query(&db, "delete from tvct where rf = %d", RF); // db.Query(&db, "delete from tvct_sub where rf = %d", RF); // db.Query(&db, "delete from cvct where rf = %d", RF); // db.Query(&db, "delete from cvct_sub where rf = %d", RF); // DeleteCDB(&db); int i; DBLock(true); for (i =0 ; i < DB_TVCT_MAX; i++) { if (db_tvct[i].rf != RF) continue; memset(&db_tvct[i], 0, sizeof(_DB_TVCT_)); } for (i =0 ; i < DB_TVCT_SUB_MAX; i++) { if (db_tvct_sub[i].rf != RF) continue; memset(&db_tvct_sub[i], 0, sizeof(_DB_TVCT_SUB_)); } #if CVCT_SUPPORT for (i =0 ; i < DB_CVCT_MAX; i++) { if (db_cvct[i].rf != RF) continue; memset(&db_cvct[i], 0, sizeof(_DB_CVCT_)); } for (i =0 ; i < DB_CVCT_SUB_MAX; i++) { if (db_cvct_sub[i].rf != RF) continue; memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_)); } #endif DBLock(false); CT_ChMapUpdate(); } // VCT ¸ð´ÏÅ͸µ Àç½ÃÀÛ hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT); #if CVCT_SUPPORT hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT); #endif } int nPos = 0; int i; for ( i = 0; i < MAX_PMT_COUNT; i++) { if (hPMT[i]) DHL_SI_MonitorStop(&hPMT[i]); } for ( i = 0; i < pat->numPrograms; i++) { if (pat->programs[i].program_map_PID == 0) continue; if (pat->programs[i].program_map_PID == 0x1FFF) continue; hPMT[nPos] = DHL_SI_MonitorPMT(RF, POS_PMT+nPos, pat->programs[i].program_map_PID, pat->programs[i].program_number); nPos++; if (nPos >= MAX_PMT_COUNT) break; } remain_pmt_count = nPos; } if (msg.nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT) { MPEG_PMT *pmt = (MPEG_PMT*)msg.SI; if (CT_ChMapUpdatePMT(RF, pmt, msg.nRequestID-POS_PMT+1, msg.CRC32)) { CT_ChMapUpdate(); } remain_pmt_count--; CT_CallBack(CT_SCAN_RECEIVE_PMT, RF, pmt->program_number, remain_pmt_count,0,0,0); if (0) DST_Printf("remain_pmt_count = %d\n", remain_pmt_count); } } DST_FreeAtscTable(&msg.SI); // ¸Þ¸ð¸® ÇØÁ¦´Â ¿©±â¿¡¼­ } // while if (startTick > DST_OS_GetTickCount()) startTick = DST_OS_GetTickCount(); CT_CallBack(CT_SCAN_PSIP_WAIT, RF, (DST_OS_GetTickCount() - startTick) * 1000/DST_OS_GetTicksPerSecond(),0,0,0,0); // PSIP ¸ðµðÅ͸µ ½ÃÀÛ ÈÄ ¸î msÀÌ Áö³µ´ÂÁö } else // bStart == false { T(); CT_ScanPSIP(0, false); bStart = true; g_bRemovedOldChannel = false; startTick = DST_OS_GetTickCount(); hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT); #if CVCT_SUPPORT hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT); #endif // hPAT = DHL_SI_MonitorPAT(RF, POS_PAT); } } else { if (bStart) { T(); DHL_SI_MonitorStop(&hTVCT); // DHL_SI_MonitorStop(&hCVCT); DHL_SI_MonitorStop(&hPAT); int i; for ( i = 0; i < MAX_PMT_COUNT; i++) { DHL_SI_MonitorStop(&hPMT[i]); } bStart = false; g_bRemovedOldChannel = false; startTick = 0; CT_SI_Msg msg; DS_U32 retLen = 0; while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError) { if (0) DST_Printf("Remove msg.nRequestID == %d\n", (int)msg.nRequestID); DST_FreeAtscTable(&msg.SI); } } } } static void CT_Scan(DS_U8 RF/*=0*/, bool bOn/*=false*/) { static bool bStart = false; static DS_U8 CurrentRF = 0; static DS_U32 startTick = 0; if (bOn) { if (bStart == false || CurrentRF != RF) { CT_ScanPSIP(0, false); DHL_TUN_Start(RF, DHL_MODULATION_8VSB); DST_g_LastTuneTime = DST_OS_GetTickCount(); CurrentRF = RF; //bLock = false; bStart = true; startTick = DST_OS_GetTickCount(); } CT_ScanPSIP(RF, bOn); bool bLock = false; int ss = 0, power = 0, snr = 0; DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr); if (startTick > DST_OS_GetTickCount()) startTick = DST_OS_GetTickCount(); CT_CallBack(CT_SCAN_LOCK_WAIT, RF, (DST_OS_GetTickCount() - startTick) * 1000/DST_OS_GetTicksPerSecond() , ss, power,0,0); } else { CT_ScanPSIP(0, false); // SCAN PSIP ¸ð´ÏÅ͸µ Ãë¼Ò if (bStart) { DST_g_LastTuneTime = 0; DHL_TUN_Stop(); bStart = false; CurrentRF = 0; startTick = 0; //bLock = false; } } } static void CT_RF_Update(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/, bool bOn /*=false*/) { static bool bStart = false; static DHL_HANDLE hRfUpdate = 0; if (bOn) { if (bStart == false) { DHL_TUN_Start(RF, demod); hRfUpdate = DHL_SI_MonitorRFUpdate(RF, POS_RFUPDATE); bStart = true; } else { // ½ÅÈ£ Á¤º¸ bool bLock = false; int ss = 0, power = 0, snr = 0; DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr); CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0); } } else { if (bStart == true) { DHL_SI_MonitorStop(&hRfUpdate); DHL_TUN_Stop(); bStart = false; } } } // CMB OTC ¸¦ À§ÇØ ¸ÕÀú CVT¸¸ È®ÀÎÇÑ´Ù. static void CT_CVT(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/, bool bOn/*=false*/) { static bool bStart = false; static DHL_HANDLE hCVT = 0; if (bOn) { if (bStart == false) { DHL_TUN_Start(RF, demod); hCVT = DHL_SI_MonitorSCTE_CVT(RF, POS_CVT); bStart = true; } else { // ½ÅÈ£ Á¤º¸ bool bLock = false; int ss = 0, power = 0, snr = 0; DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr); CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0); } } else { if (bStart == true) { DHL_SI_MonitorStop(&hCVT); DHL_TUN_Stop(); bStart = false; } } } static void CT_OTC(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/, DS_U16 otc_pid /*= 0*/, bool bOn/*=false*/) { static bool bStart = false; static DHL_HANDLE hDII = 0; static DHL_HANDLE hDDB = 0; if (bOn) { if (bStart == false) { DHL_TUN_Start(RF, demod); DST_g_LastTuneTime = DST_OS_GetTickCount(); //CT_CallBack(CT_OTC_START); hDII = DHL_SI_MonitorSCTE_DII(RF, POS_OTC_DII, otc_pid); hDDB = DHL_SI_MonitorSCTE_DDB(RF, POS_OTC_DDB, otc_pid); bStart = true; } else { // ½ÅÈ£ Á¤º¸ bool bLock = false; int ss = 0, power = 0, snr = 0; DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr); CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0); } } else { if (bStart == true) { DST_g_LastTuneTime = 0; DHL_SI_MonitorStop(&hDII); DHL_SI_MonitorStop(&hDDB); DHL_TUN_Stop(); bStart = false; } } // if(DST_OTC_GetStatus() == CD_INBAND_DOWNLOAD) // { // if(hDII) // { // DHL_SI_MonitorStop(&hDII); // hDII = 0; // } // if(hDDB == 0) // { // hDDB = DHL_SI_MonitorSCTE_DDB(RF, POS_OTC_DDB, otc_pid); // } // } // if(DST_OTC_GetStatus() == CD_INBAND_DOWNLOAD_UPDATE) // { // if(hDDB) // { // DHL_SI_MonitorStop(&hDDB); // hDDB = 0; // } // } } static void CT_VideoFreezeEndProc() { if (0) DST_Printf("DST_VideoFreezeEndProc\n"); CT_ChannelChangeVideoMute(false); } static void CT_SignalInfoCallBack(int nWidth, int nHeight, int RefreshRate, bool bInterlaced, DHL_SOURCE_ASEPCT Aspect) { CT_CallBack(CT_VIDEO_RESOLUTION, nWidth, nHeight, RefreshRate, bInterlaced, Aspect,0); } void DST_708_Callback(DS_U8 *bytearray,int size); void DST_IrCallBack(DS_U32 key, DS_U32 repeat, DS_U32 tick); static bool g_VideoDisplay = true; void JST_POWER_Display(bool bOn) { g_VideoDisplay = bOn; } static void tChannel(void) { DHL_SYS_TV_Open(CT_SignalInfoCallBack, CT_VideoFreezeEndProc, 0, CT_SI_Proc, DST_708_Callback, DST_IrCallBack); CT_Msg msg = {CMD_NULL, DHL_MODULATION_8VSB, 0,0}; while (1) { DS_U32 retLen; CT_Msg tmp; bool bChanged = false; // ½×¿©ÀÖ´Â ¸ðµç ¸Þ½ÃÁö¸¦ °¡Á®¿Â´Ù. #ifdef DSTAR DST_OS_Delay(50); #else DST_OS_Delay(10); #endif while (DST_OS_ReceiveMessage_NoWait(gMsgQ, (DS_U32*)&tmp, sizeof(CT_Msg), &retLen) == noError) { if (0) DST_Printf("\n\n\n\n\nReceive Cmd = %d RF = %d demod = %d program_number = %d\n\n\n\n\n\n", tmp.Cmd, tmp.RF, tmp.demod, tmp.program_number); if (msg.Cmd != tmp.Cmd || msg.RF != tmp.RF || msg.demod != tmp.demod || msg.program_number != tmp.program_number) { msg = tmp; bChanged = true; } } ////if (0) DST_Printf("Current Cmd = %d RF = %d Minor = %d Mode = %d\n", msg.Cmd, msg.RF, msg.Minor, msg.Mode); static DS_U16 program_number = 0; static DS_U16 source_id = 0; if (msg.Cmd == CMD_TUNE) { DBLock(true); DS_U16 new_program_number = 0; DS_U16 new_source_id = 0; if (msg.program_number == 0) // RF Æ©´×ÀÎ °æ¿ì { int i; int min_minor = 10000; int min_minor_pos = -1; for (i = 0; i < DB_CHANNEL_DB_MAX; i++) { if (db_channel_db[i].program_number == 0) continue; if (db_channel_db[i].rf != msg.RF) continue; if (min_minor > db_channel_db[i].minor) { min_minor = db_channel_db[i].minor; min_minor_pos = i; } } if (min_minor_pos >= 0) { new_program_number = db_channel_db[min_minor_pos].program_number; new_source_id = db_channel_db[min_minor_pos].source_id; } } else { int i; for (i = 0; i < DB_CHANNEL_DB_MAX; i++) { if (db_channel_db[i].program_number == 0) continue; if (db_channel_db[i].program_number != msg.program_number) continue; if (db_channel_db[i].rf != msg.RF) continue; new_program_number = db_channel_db[i].program_number; new_source_id = db_channel_db[i].source_id; break; } } if (program_number != new_program_number || source_id != new_source_id) { program_number = new_program_number; source_id = new_source_id; bChanged = true; } DBLock(false); } else { program_number = 0; source_id = 0; } switch (msg.Cmd) { case CMD_NULL: break; case CMD_TUNE: CT_Scan(0, false); CT_OTC(0, DHL_MODULATION_256QAM, 0, false); CT_RF_Update(0, DHL_MODULATION_256QAM, false); CT_CVT(0, DHL_MODULATION_256QAM, false); CT_Tune(msg.RF, msg.demod, program_number, source_id, true); if (bChanged) CT_CallBack(CT_TUNE_START, msg.RF, program_number, source_id,0,0,0); CT_AutoScanMute(false); break; case CMD_SCAN: CT_AutoScanMute(true); CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false); CT_OTC(0, DHL_MODULATION_256QAM, 0, false); CT_RF_Update(0, DHL_MODULATION_256QAM, false); CT_CVT(0, DHL_MODULATION_256QAM, false); CT_Scan(msg.RF, true); if (bChanged) CT_CallBack(CT_SCAN_START, msg.RF,0,0,0,0,0); break; case CMD_RF_UPDATE: CT_AutoScanMute(true); CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false); CT_Scan(0, false); CT_OTC(0, DHL_MODULATION_256QAM, 0, false); CT_CVT(0, DHL_MODULATION_256QAM, false); CT_RF_Update(msg.RF, msg.demod, true); if (bChanged) CT_CallBack(CT_RF_UPDATE_START, msg.RF,0,0,0,0,0); break; case CMD_CVT: CT_AutoScanMute(true); CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false); CT_Scan(0, false); CT_RF_Update(0, DHL_MODULATION_256QAM, false); CT_OTC(0, DHL_MODULATION_256QAM, 0, false); CT_CVT(msg.RF, msg.demod, true); if (bChanged) CT_CallBack(CT_CVT_START, msg.RF, msg.program_number,0,0,0,0); break; case CMD_OTC: CT_AutoScanMute(true); CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false); CT_Scan(0, false); CT_RF_Update(0, DHL_MODULATION_256QAM, false); CT_CVT(0, DHL_MODULATION_256QAM, false); CT_OTC(msg.RF, msg.demod, msg.program_number, true); if (bChanged) CT_CallBack(CT_OTC_START, msg.RF, msg.program_number,0,0,0,0); break; case CMD_OTC_STOP: CT_OTC(0, DHL_MODULATION_256QAM, 0, false); break; case CMD_STOP: CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false); CT_Scan(0, false); CT_OTC(0, DHL_MODULATION_256QAM, 0, false); CT_RF_Update(0, DHL_MODULATION_256QAM, false); if (bChanged) CT_CallBack(CT_STOPPED,0,0,0,0,0,0); break; } DHL_POWER_Display(g_VideoDisplay); if (msg.Cmd == CMD_CLOSE) break; } CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false); CT_Scan(0, false); DHL_SYS_TV_Close(); CT_CallBack(CT_CLOSE, 0, 0, 0, 0,0,0); DST_OS_DeleteMessageQueue(gMsgQ); DST_OS_DeleteMessageQueue(gSIMsgQ); gMsgQ = 0; gSIMsgQ = 0; // DST_DB_Close(); g_callback = 0; DST_OS_SelfDeleteTask(); } static void CT_Init() { static int taskID = 0; // ŽºÅ©¿Í ¸Þ½ÃÁöÅ¥ »ý¼º if (taskID == 0) { gMsgQ = DST_OS_CreateMessageQueue("qChannelTask", 0, 100, sizeof(CT_Msg)); gSIMsgQ = DST_OS_CreateMessageQueue("qChannelTask", 0, 100, sizeof(CT_SI_Msg)); taskID = DST_OS_SpawnTask((void (*)(void *)) tChannel, (char*)"tChannel", APP_TASK_PRIO_CHANNEL, WIN_MGR_TASK_STACKSIZE, 0); } } // jstack open void JST_Open(jst_callback callcack) { g_callback = callcack; CT_Init(); } static void JST_SendMsg(int Cmd /*= CMD_NULL*/, DS_U32 RF /*= 0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, DS_U16 program_number /*= 0*/) { switch (demod) { case DHL_MODULATION_64QAM:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|64QAM|%d\n", __func__, Cmd, RF, program_number);break; case DHL_MODULATION_256QAM:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|256QAM|%d\n", __func__, Cmd, RF, program_number);break; case DHL_MODULATION_8VSB:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|8VSB|%d\n", __func__, Cmd, RF, program_number);break; case DHL_MODULATION_16VSB:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|16VSB|%d\n", __func__, Cmd, RF, program_number);break; default: break; } CT_Init(); CT_Msg msg; msg.Cmd = Cmd; msg.RF = RF; msg.demod = demod; msg.program_number = program_number; if (gMsgQ) DST_OS_SendMessage(gMsgQ, (DS_U32 *)&msg, sizeof(CT_Msg)); } // jstack close void JST_Close() { JST_SendMsg(CMD_CLOSE, 0, DHL_MODULATION_8VSB, 0); } // Channel Task Start void JST_Tune(DS_U8 RF, DHL_MODULATION_MODE demod, DS_U16 program_number) { JST_SendMsg(CMD_TUNE, RF, demod, program_number); } // Channel Task Start void JST_Scan(DS_U8 RF) { DST_Printf("JST_Scan %d\n", RF); JST_SendMsg(CMD_SCAN, RF, DHL_MODULATION_8VSB, 0); } void JST_RFUpdate(DS_U8 RF) { T(); JST_SendMsg(CMD_RF_UPDATE, RF, DHL_MODULATION_8VSB, 0); } void JST_CVT(DS_U8 RF, DHL_MODULATION_MODE demod) { JST_SendMsg(CMD_CVT, RF, demod, 0); } void JST_OTC(DS_U8 RF, DHL_MODULATION_MODE demod, DS_U16 otc_pid) { JST_SendMsg(CMD_OTC, RF, DHL_MODULATION_256QAM, otc_pid); } void JST_OTC_STOP() { JST_SendMsg(CMD_OTC_STOP, 0, DHL_MODULATION_8VSB, 0); } // Channel Task Stop void JST_Stop(void) { JST_SendMsg(CMD_STOP, 0, DHL_MODULATION_8VSB, 0); }