/* DMW_ChannelTune.c */ #include "DMW_Platform.h" #include "DHL_DBG.h" #define Demux_tsdStart(a,b) #include "DMW_Config.h" #include "DMW_DebugUtil.h" #include "DMW_Status.h" #include "DMW_Channel.h" #include "DMW_ChannelUtil.h" #include "DMW_ChannelDemux.h" #include "DMW_ChannelPM.h" // Performance monitor //#include DHL_MODULE("$dmc", 1); #if USE_PERF_MON static char *PM_EV_Name[] = { "Total", // total elapsed time for tuning "Stop", // previous video stop "Lock", // tuner/demod lock "PSIP", // download psip "PSI", // download psi "AV", // video+audio "Video", // video context creation "Audio", // audio start and detect "Callback", // tune complete callback }; DHL_PM_HANDLE gDmcPMTune; #endif // Config Param: [0 ~ 100] Tuner µå¶óÀ̹öÀÇ ½ÅÈ£¼¼±â ¸®ÅÏ ¹üÀ§ ÁöÁ¤ // // µðÁöÅРä³Î¿¡¼­ Signal strengh threshold // // channel scanÀ» ÁøÇàÇϱâ À§ÇØ ÇÊ¿äÇÑ ÃÖÀú ½ÅÈ£ ¼¼±â. // ¼³·É lockÀÌ µÇ¾ú´õ¶óµµ ÀÌ ½ÅÈ£¼¼±â¸¸Å­ ÀâÈ÷Áö ¾ÊÀ¸¸é ä³Î LockÀÌ ¾ÈµÈ °ÍÀ¸·Î // °£ÁÖÇÑ´Ù. ÀÌ °ªÀº µðÁöÅРä³Î¿¡¼­¸¸ Àû¿ëµÈ´Ù. // 0Àº Ưº°ÇÑ Àǹ̷μ­, ½ÅÈ£¼¼±â¿¡ ¹«°üÇÏ°Ô lock ¿©ºÎ·Î¸¸ ÆÇ´ÜÇÏ¿© ÁøÇàÇϵµ·Ï // ÇÑ´Ù. // int g_SignalThresholdForDigitalChannel = 0; // // Config Param: TRUE or FALSE // // Å×½ºÆ® º¯¼ö // // TRUEÀ̸é tuningÇÒ ¶§ signal lock üũ¸¦ ÇÏÁö ¾Ê´Â´Ù. // signal °ü·ÃµÈ Å×½ºÆ®¸¦ ÇÒ ¶§ »ç¿ë. // int gDmcTestSkipCheckSignalLock = 0; // // Config Param: TRUE or FALSE // // Å×½ºÆ® º¯¼ö // // TRUEÀ̸é tuningÇÒ ¶§ VCT¸¦ ¼ö½ÅÇÏÁö ¸øÇÑ °Í ó·³ µ¿ÀÛÇÑ´Ù. // // cafrii 060628 addd // int gDmcTestSkipVctDownload = 0; // TuneParam // 1. AV Decoding¿¡ ÇÊ¿äÇÑ Request Parameter. RfTuneÀÇ ÇÔ¼ö ÀÎÀÚ·Î applicationÀÌ Á¦°ø. // 2. TuneCallbackÀ» ÅëÇØ¼­ tuningÀÇ °á°ú°¡ ³Ñ°ÜÁú¶§ Dmc code°¡ app·Î Á¦°øÇÔ. typedef struct { TuneParam param; int rf, program_number; // ÀÌ Á¤º¸´Â video cache indicator·Î »ç¿ëµÈ´Ù. // Video/Audio decoding.. UINT32 pcrPid, vidPid, audPid; // cafrii 070718 add BOOL pid_tune_fail_count; UINT32 pid_tune_fail_time; MPEG_PAT *pat; MPEG_PMT *pmt; xvctPtr_t vct; VideoStreamDescriptor *vidDesc; tDHL_VideoCodingType vidType; /* add for avc */ tDHL_AudioCodingType audType; } ChannelTuneContext; #if COMMENT _______DMC_CORE3________(){} #endif //------------------------------------------------------- xvctChannelPtr_t doDmc_FindNextVctChannel(xvctPtr_t vctPtr, UINT32 currentMajorMinor, BOOL bSkipNonFamilyChannel, BOOL bSkipHiddenChannel) { int i; xvctChannelPtr_t channel; UINT32 minMajorMinor, tmpMajorMinor; int minIndex; UINT16 major, minor; if (!vctPtr) return NULL; // ÁöÁ¤µÈ ä³Î ¹øÈ£ (currentMajorMinor) ºÎÅÍ °Ë»ö. // // currentMM º¸´Ù Å« MM Áß¿¡¼­ ÃÖ¼Ò MMÀ» ã´Â´Ù. // ´Ü CTF_RetryOtherFamilyChannel ¸ðµå¿¡¼­´Â Major°¡ °°Àº ä³Î·Î Á¦ÇÑÇÔ. // //dprint(2, " find minimum minor..\n"); minMajorMinor = (UINT32)(-1); minIndex = -1; for (i=0; inumChannels; i++) { channel = &vctPtr->channel[i]; if (channel == NULL) continue; major = Dmc_GetMajorNumber(vctPtr->is_cvct, channel); minor = Dmc_GetMinorNumber(vctPtr->is_cvct, channel); if (bSkipHiddenChannel && channel->hidden) continue; if (bSkipNonFamilyChannel && (currentMajorMinor >> 16)) { // FamilyChannel ¸ðµå: ¹ß°ßµÇ¾ú´õ¶óµµ Major°¡ ²À ÀÏÄ¡ÇØ¾ß ÇÑ´Ù. // if ((currentMajorMinor >> 16) != major) { dprint(2, "!! skip non-family channel %d,%d\n", major, minor); continue; } } //dprint(2, " [%d] %d-%d\n", i, major, minor); tmpMajorMinor = (major<<16UL) + minor; if (currentMajorMinor >= tmpMajorMinor) continue; // ´õ ÀÛÀº ä³Î¹øÈ£. skip! if (minMajorMinor > tmpMajorMinor) { minMajorMinor = tmpMajorMinor; minIndex = i; } } if (minIndex < 0) // ´õÀÌ»ó ¾øÀ½. return NULL; channel = &vctPtr->channel[minIndex]; return channel; } // cafrii 060710 add // // vctÀÇ program number¿¡ ÇØ´çÇÏ´Â ÇÁ·Î±×·¥ÀÌ PAT¿¡ ¾ø´Â °æ¿ì, // vctÀÇ program numberÀÇ PMT°¡ ¼ö½ÅÀÌ ¾ÈµÇ´Â °æ¿ì, // vctÀÇ program number Á¤º¸°¡ À߸øµÈ °ÍÀ¸·Î °¡Á¤ÇÏ°í º¹±¸¸¦ ¼öÇàÇÑ´Ù. // µî·ÏµÈ ¸ðµç PMT¸¦ ¼ö½ÅÇØ¼­ °¡Àå ºñ½ÁÇÑ PMTÀÇ program number·Î ±³Ã¼ÇÑ´Ù. // // [IN] xvctChannelPtr_t channel : º¹±¸ÇÒ vct channel. // pat // // [OUT] »õ·Ó°Ô ¼ö½Å µÈ pmt // STATUS doDmc_RecoverVctProgramNumber(ChannelTuneContext *ctx, xvctChannelPtr_t channel) { STATUS status; int k; int _second = 1000; MPEG_PAT *pat = ctx->pat; MPEG_PMT *pmt = NULL; PidInfo pid1, pid2; if (channel == NULL) return statusInvalidArgument; dprint(2, "doDmc_RecoverVctProgramNumber(#%d):\n", channel->program_number); if (ctx->pmt) { dprint(2, "\tfree previous PMT.. program num %d\n", ctx->pmt->program_number); FreePMT(ctx->pmt); ctx->pmt = NULL; } if (ctx->pat == NULL) return statusInvalidPSI; // PAT ¼ö½ÅÀ» ´õÀÌ»ó ½ÃµµÇÏÁö ¾Ê´Â´Ù. // ÀÌ ÇÔ¼ö°¡ ºÒ¸®´Â ´Ü°è¶ó¸é ÀÌ¹Ì ¸î ¹ø PAT ¼ö½Å¿¡ ½ÇÆÐÇÑ °æ¿ìÀÏ °ÍÀÓ. // if (pat->numPrograms == 0 || pat->programs == NULL) { dprint(1, "!! invalid PSI.. no program in pat?\n"); status = statusInvalidPSI; goto label_end_function; } //-------------------- // VCT processing memset(&pid1, 0, sizeof(pid1)); status = Dmc_GetInfoFromVctDesc(channel->descriptors, channel->descriptor_length, &pid1, NULL); if (status) { dprint(2, "!! vct pid info invalid. cannot recover\n"); return statusInvalidVCT; } //-------------------- // PMT processing dprint(2, " load %d pmts\n", pat->numPrograms); for (k=0; knumPrograms; k++) { dprint(2, " [%d] get pmt #%d, pid %x\n", k, pat->programs[k].program_number, pat->programs[k].program_map_PID); if (pmt) { FreePMT(pmt); pmt = NULL; // cafrii 060719 bugfix!! PR DS075 fix } status = Dmc_GetPMT(Dmc_GetCurrentTsd(), pat->programs[k].program_map_PID, pat->programs[k].program_number, &pmt, g_Timeout_PmtLoading*_second/1000, Dmc_CheckCancel); if (status == statusCancelled) goto label_cancelled; else if (status) { dprint(2, "\t !! PMT[%d] load failed, %d\n", k, status); continue; } // pmtÀÇ pid Á¤º¸¿Í, vctÀÇ pid Á¤º¸°¡ ÀÏÄ¡ÇÏ¸é ¼­·Î °°Àº programÀ¸·Î º¸°í // vctÀÇ program number¸¦ ¼öÁ¤ÇÏÀÚ! status = Dmc_GetPidInfoFromPMT(pmt, &pid2); if (status) { dprint(2, "\t PMT[%d] pid info err %d\n", k, status); continue; } if (pid1.pcr == pid2.pcr && pid1.video == pid2.video && pid1.audio == pid2.audio) { dprint(2, "\tcorrect pmt found. recover #%d -> #%d\n", channel->program_number, pmt->program_number); channel->program_number = pmt->program_number; if (ctx->pmt) FreePMT(ctx->pmt); ctx->pmt = pmt; pmt = NULL; goto label_end_function; } } dprint(2, "\tproper pmt not found.\n"); goto label_end_function; label_cancelled: status = statusCancelled; label_end_function: if (pmt) FreePMT(pmt); return status; } // // ÇØ´ç program number¿¡ ÇØ´çÇÏ´Â PAT/PMT¸¦ ¼ö½ÅÇÑ´Ù. // statusOK // statusInvalidPSI // statusNoPSI // statusCancelled // STATUS doDmc_GetPmtByProgramNumber(ChannelTuneContext *ctx, UINT16 program_number) { return Dmc_GetPmtByProgramNumber(&(ctx->pat), &(ctx->pmt), program_number, doDmc_CheckCancel); } // cafrii 070201 add void doDmc_NotifyPidInfo(UINT16 uVidPid, UINT16 uAudPid, UINT16 uPcrPid, UINT16 uPmtPid) { DecodingPidReadyParam dprp; dprp.vid_pid = uVidPid; dprp.aud_pid = uAudPid; dprp.pcr_pid = uPcrPid; dprp.pmt_pid = uPmtPid; doDmc_Notify(DMW_NOTIFY_DecodingPidReady, (UINT32) &dprp); } // doDmc_DownloadTables // // Digital tuning ¿¡¼­ È£ÃâµÇ¾î TVCT, CVCT, PAT¸¦ µ¿½Ã¿¡ ¼ö½ÅÇÑ´Ù. // ¼ö½ÅµÈ VCTµéÀº xvct·Î ÅëÇÕµÇ¾î °ü¸®µÈ´Ù. // // ¸®ÅϰªÀº statusOK ¾Æ´Ï¸é statusCancelled ¸¸ °¡´ÉÇÏ´Ù. // ÀÚ¼¼ÇÑ ¿¡·¯ »óȲÀº ¸®ÅϵÇÁö ¾ÊÀ¸¸ç, °á°ú pointer¸¦ º¸°í ÆÇ´ÜÇØ¾ß ÇÑ´Ù. // STATUS doDmc_DownloadTables(ChannelTuneContext *ctx) { tvctPtr_t tvct = NULL; cvctPtr_t cvct = NULL; STATUS status; int _second = 1000; //------------ dprint(1, "downloading tables..\n"); //------------- // ÀÌ¹Ì TuneParam¿¡ ¹º°¡ ¹Þ¾ÆÁø°Ô ÀÖÀ¸¸é »èÁ¦ÇÑ´Ù. // ÀÌ ÇÔ¼ö´Â RfTune Ãʱ⿡ ºÒ¸®±â ¶§¹®¿¡ ¾î¶°ÇÑ tableµµ ¹Þ¾ÆÁ®ÀÖÀ¸¸é ¾ÈµÈ´Ù. ctx->vct = NULL; ctx->pat = NULL; //------ Table ·Îµù (synchornous ¹æ½Ä) status = Dmc_GetVctAndPat(Dmc_GetCurrentTsd(), &tvct, &cvct, &ctx->pat, g_Timeout_VctLoading*_second/1000, Dmc_CheckCancel); // // pat¿Í (tvct³ª cvct) µÑ Áß Çϳª¸¸ ¼ö½ÅµÇ¸é ÀÏ´Ü ¸®ÅÏÇÑ´Ù. // ¹°·Ð µ¿½Ã¿¡ µÑ ´Ù ¼ö½ÅµÉ °¡´É¼ºµµ ÀÖ´Ù. if (status == statusCancelled) return statusCancelled; // TVCT, CVCT°¡ µÑ ´Ù ¼ö½ÅÀÌ ¾ÈµÉ ¼öµµ ÀÖ´Ù. ¼³·É PAT´Â ¼ö½ÅÀÌ µÇ¾ú´Ù°í ÇÏ´õ¶óµµ // ÁøÇàÇÏÁö´Â ¾Êµµ·Ï ÇÏÀÚ. // if (tvct == NULL && cvct == NULL) { dprint(1, "!! No VCTs found\n"); return statusNoVCT; // ¸®ÅϰªÀº º° Àǹ̰¡ ¾ø´Ù. } // Antenna ¸ðµå¿¡¼­´Â CVCT°¡ ¼ö½ÅÀÌ µÇ¾ú¾îµµ À̰ÍÀ» »ç¿ëÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. if (cvct && g_CurChannelType == ChannelType_Cable) { status = Dmc_TranslateCvct(cvct, &(ctx->vct)); if (status == statusOK) dprint(2, "\tCVCT found. total %d channels\n", ctx->vct->numChannels); else { dprint(0, "!! cvct->vct err %d\n", status); ctx->vct = NULL; } } else if (tvct) { status = Dmc_TranslateTvct(tvct, &(ctx->vct)); if (status == statusOK) dprint(2, "\tTVCT found. total %d channels\n", ctx->vct->numChannels); else { dprint(0, "!! cvct->vct err %d\n", status); ctx->vct = NULL; } } if (tvct) FreeAtscTable(tvct); if (cvct) FreeAtscTable(cvct); if (gDmcTestSkipVctDownload) // cafrii 060628 add Dmc_FreeAtscTable(&ctx->vct); return status; } // doDmc_TuneByVctChannel // // ¼±ÅÃµÈ VCT subchannel Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© µðÁöÅÐ Æ©´×À» ¼öÇàÇÑ´Ù. // Æ©´×Çϱâ Àü¿¡ Ç×»ó ÀÏÄ¡ÇÏ´Â PSI Á¤º¸°¡ ÀÖ´ÂÁö¸¦ È®ÀÎÇÑ´Ù. // // statusOK // statusInvalidPSI, statusInvalidVCT, statusNoPSI // statusVideoError // statusCancelled // STATUS doDmc_RfTuneByVctSubChannel(ChannelTuneContext *ctx, xvctChannelPtr_t channel) { STATUS status; TuneParam *tuneParam = &ctx->param; DMC_VIDEO_CACHE cache; PidInfo pidinfo; if (channel == NULL) return statusInvalidArgument; dprint(2, "\ttune vct subchannel #%d\n", channel->program_number); #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 0); #endif status = doDmc_GetPmtByProgramNumber(ctx, channel->program_number); if (status == statusCancelled) // PMT ¹Þ´Â ÀÛ¾÷Àº blocking ÀÛ¾÷À̹ǷΠcancel üũ ÇÊ¿ä. return statusCancelled; if (status != statusOK || ctx->pat == NULL || ctx->pmt == NULL) { if (tuneParam->flag & CTF_DontUseVctRecover) return statusInvalidVCT; // cafrii 060707 add // vctÀÇ program number°¡ À߸øµÈ °æ¿ì°¡ ÀÖ´Ù. // vct¸¦ ºñ·ÔÇÑ PSIP¿¡´Â ¿©·¯ ¸¹Àº Á¤º¸°¡ ÀÖÀ¸¹Ç·Î, // À̸¦ ±×³É ¹ö¸®±â´Â ¾Æ±õ´Ù. // ±×·¡¼­ smart ÇÏ°Ô program number¸¦ º¹±¸ÇÏ´Â ÀÛ¾÷À» ¼öÇàÇÑ´Ù. status = doDmc_RecoverVctProgramNumber(ctx, channel); // ¼öÇà °á°ú¿¡ µû¶ó channel->program_number°¡ º¯°æ µÉ ¼öµµ ÀÖ´Ù. if (status == statusCancelled) // PMT ¹Þ´Â ÀÛ¾÷Àº blocking ÀÛ¾÷À̹ǷΠcancel üũ ÇÊ¿ä. return statusCancelled; } // cafrii 070718 change // ³ªÁß¿¡ pid°¡ ¿ÏÀüÈ÷ °áÁ¤ µÈ ÈÄ¿¡ updateÇϵµ·Ï ÇÏÀÚ. //ctx->pcrPid = ctx->vidPid = ctx->audPid = 0; status = Dmc_DecidePidInfo2(ctx->pmt, channel->descriptors, channel->descriptor_length, &pidinfo, 0); if (status == statusOK && pidinfo.bValid) { dprint(2, "\t pid decided. pva %x %x %x, type va %d %d\n", pidinfo.pcr, pidinfo.video, pidinfo.audio, pidinfo.videoType, pidinfo.audioType); } else { pidinfo.pcr = pidinfo.video = pidinfo.audio = 0; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 1); #endif doDmc_SelectAudioStream(ctx->pmt, channel, &(pidinfo.audio), &(pidinfo.audioType)); doDmc_SelectVideoStream(ctx->pmt, channel, &(pidinfo.video), &(pidinfo.videoType)); if (pidinfo.pcr == 0 || (pidinfo.video == 0 && pidinfo.audio == 0)) { dprint(1, "!! No valid video or audio pid..\n"); return statusInvalidVCT; } // cafrii 070718 add check. // ÀÌ Àü¿¡ ÀÌ¹Ì ½ÇÆÐÇÑ pid¶ó¸é ´Ù½Ã ½ÃµµÇÒ Çʿ䰡 ¾øÀ½. if (ctx->pid_tune_fail_count > 0 && DHL_OS_GetMsCount() - ctx->pid_tune_fail_time < 1000*20 && ctx->pcrPid == pidinfo.pcr && ctx->vidPid == pidinfo.video && ctx->audPid == pidinfo.audio && ctx->vidType == pidinfo.videoType && ctx->audType == pidinfo.audioType) { dprint(0, "!! pid pvat (%x %x %x %x) already failed at %u ms before..\n", ctx->pcrPid, ctx->vidPid, ctx->audPid, ctx->audType, (DHL_OS_GetMsCount() - ctx->pid_tune_fail_time)*1000/1000); return statusInvalidVCT; } ctx->pcrPid = pidinfo.pcr; ctx->vidPid = pidinfo.video; ctx->audPid = pidinfo.audio; ctx->audType = pidinfo.audioType; ctx->vidType = pidinfo.videoType; // ¸ðµç pid Á¤º¸°¡ Áغñ µÇ¾úÀ½. // ƯÁ¤ descramble systemÀÇ °æ¿ì pmt pid Á¤º¸¸¦ ÇÊ¿ä·Î Çϱ⵵ ÇϹǷΠ// callbackÀ» ÅëÇØ¼­ pid Á¤º¸¸¦ notifyÇØÁØ´Ù. if (ctx->pmt) { // cafrii 070711 bugfix! check pmt null // cafrii 070201 add doDmc_NotifyPidInfo(ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->pmt->PID); } dprint(2, "\tdecoding p%x, v%x(t%d), a%x(t%d) start..\n", ctx->pcrPid, ctx->vidPid, ctx->vidType, ctx->audPid, ctx->audType); // arzhna, 100203 // VCT¿¡ ÀÇÇÑ Tuneµµ CA PMT¸¦ Àü´ÞÇϵµ·Ï ¼öÁ¤ // APP¿¡¼­ CableCardÀåÂø½Ã Æ©´× ¸ðµå¿¡ ´ëÇØ Ãë»ç ¼±ÅÃÇϵµ·Ï ÇÑ´Ù // // doDmc_Notify()·Î app¿¡ notify, // app¿¡¼­ ó¸®ÇÏ¿© CARD¿¡ reportÇÑ´Ù. { PSIChangeNotifyInfo pcni; memset(&pcni, 0, sizeof(pcni)); pcni.pmtchanged = TRUE; // This is PMT pcni.pmt = ctx->pmt; // new PMT // CableCard ¸ðµå¿¡¼­´Â PSI·Î¸¸ Æ©´×À» Çϴµ¥, // Æ©´×À» Çϱâ Àü¿¡ PMT report¸¦ ¼öÇàÇÑ´Ù. dprint(2, "\tReport CaPmt (pid %d,%d)\n", ctx->vidPid, ctx->audPid); // arzhna, 100203 // CA PMT¸¦ Àü´ÞÇϱâ À§ÇÑ callback È£Ãâ // DMC_NOTIFY_CaPmt event¸¦ º°µµ·Î ¸¸µé¾î ó¸® doDmc_Notify(DMC_NOTIFY_CaPmt, (UINT32)&pcni); } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0); #endif #if SUPPORT_DMW_VIDEO_CACHE // Ȥ½Ã cache Á¤º¸°¡ ÀÖ´ÂÁö load ÇØº»´Ù. cache = DHL_AV_LoadVideoFromCache(ctx->rf, ctx->program_number, ctx->vidPid, ctx->pcrPid); #else cache = (DMC_VIDEO_CACHE)NULL; #endif status = doDmc_StartDigital(ctx->vidPid, ctx->audPid, ctx->pcrPid, cache, ctx->vidType, ctx->audType); // Video Context¸¦ ¸¸µå´Â ÀÛ¾÷ ¿ª½Ã blocking ÀÛ¾÷À̹ǷΠcancel üũ.. if (status == statusCancelled) { doDmc_ClearProgramInfo(); return statusCancelled; } if (status) { dprint(1, "!! cannot start with CVCT pids, status %d\n", status); doDmc_ClearProgramInfo(); return status; // statusScrambled, statusVideoError, ... } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1); #endif doDmc_UpdateProgramInfoDigital(tuneParam->rf, tuneParam->type, TUNE_METHOD_ByVCT, Dmc_GetMajorNumber(ctx->vct->is_cvct, channel), //tuneParam->major Dmc_GetMinorNumber(ctx->vct->is_cvct, channel), //tuneParam->minor channel->program_number, ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->vidType, ctx->audType); // retry flag°¡ »ç¿ëµÇ¾ú´Ù¸é ½ÇÁ¦ user°¡ ÁöÁ¤ÇÑ major/minor ¿Í ´Ù¸¦ ¼ö ÀÖ´Ù. ÁÖÀÇ.. // cafrii 060725, tune paramÀÇ major/minor °ª º¸´Ù, vctÀÇ Á¤º¸¸¦ º¸¿©ÁÖÀÚ. doDmc_UpdatePsiInfo(ctx->pat, ctx->pmt); ctx->pat = NULL; ctx->pmt = NULL; return statusOK; } // doDmc_RfTuneByVct // // ´Ù¿î·Îµå ¹ÞÀº VCT¸¦ ÀÌ¿ëÇÏ¿© Æ©´×À» ÇÑ´Ù. (tuneParam->vctPtr) // TuneParam¿¡ ÀÖ´Â »ç¿ëÀÚÀÇ ¿ä±¸»çÇ×´ë·Î Æ©´×À» ÇÑ´Ù (major/minor) // // // °¡´ÉÇÑ ¸®Åϰªµé: // statusOK : AV decoding success // statusCancelled : user¿¡ ÀÇÇØ Ãë¼Ò µÇ¾úÀ½ // statusNoVCT/InvalidVCT/NoPSI // statusInvalidVCT : VCTÀÇ ³»¿ëÀÌ ¿Ã¹Ù¸£Áö ¸øÇÏ¿© ÁøÇà ¾ÈµÊ // statusChannelNotFound : »ç¿ëÀÚ°¡ ÁöÁ¤ÇÑ Ã¤³ÎÀ» ãÁö ¸øÇßÀ½. // statusVideoError : ¸ðµç Á¤º¸¸¦ Á¦´ë·Î ¼ö½ÅÇÏ¿´À¸³ª AV decoding½Ã¿¡ ¿¡·¯ ¹ß»ý STATUS doDmc_RfTuneByVct(ChannelTuneContext *ctx) { int i; STATUS status; STATUS returnStatus = statusOK; // ÃÖÁ¾ÀûÀ¸·Î ÀÌ ÇÔ¼ö¸¦ return ÇÒ ¶§ »ç¿ëÇÒ status°ª.. UINT16 major, minor; xvctChannelPtr_t channel; UINT32 currentMajorMinor; BOOL bChannelFound; TuneParam *tuneParam = &ctx->param; dprint(1, "doDmc_RfTuneByVct: %d-%d\n", tuneParam->major, tuneParam->minor); if (ctx->vct == NULL) return statusInvalidState; if (tuneParam->major == 0) { //------------------- // unspecified tuning // caller°¡ Á÷Á¢ Major/minor¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀº °æ¿ìÀÌ´Ù. // tuneParam->major, tuneParam->minor ¸ðµÎ 0 ÀÌ´Ù. // À̶§´Â ÀÚµ¿ÀûÀ¸·Î retry loopÀ¸·Î µé¾î°£´Ù. // ±×·¯³ª °è¼ÓÀûÀ¸·Î retry¸¦ ÇÒ °ÍÀÎÁö ¾Æ´ÑÁö´Â Retry flag¿¡ µû¶ó¼­ °áÁ¤µÈ´Ù. // currentMajorMinor = 0; dprint(2, "\tunspecified tuning: search from 0-0\n"); goto label_retry_vct; } // end unspecified tuning //------------------- // Specified Tuning : // Á÷Á¢ Major/minor ¹øÈ£¸¦ ÁöÁ¤Çؼ­ ±× ä³ÎÀ» Æ©´×ÇÏ´Â ¹æ¹ý // CTF_RetryMainChannelÀÌ setµÇ¸é Mainä³ÎÀº ´Ù½Ã Æ©´× ½Ãµµ ÇÑ´Ù. (1ȸÇÑ) // // find 'the channel' major-minor. Á¤È®ÇÏ°Ô ÀÏÄ¡ÇÏ´Â M-m ä³ÎÀ» ã¾Æ¾ß¸¸ ÇÑ´Ù. // bChannelFound = FALSE; // caller´Â Á÷Á¢ÀûÀ¸·Î OnePartNumber·Î È£ÃâÇßÀ» ¼öµµ ÀÖ°í, (minor°¡ ƯÁ¤ indication°ª) // Raw major/minor·Î È£ÃâÇßÀ» ¼öµµ ÀÖ´Ù. (major »óÀ§ 6ºñÆ®°¡ 1) // if (tuneParam->minor == ONE_PART_CHANNEL_INDICATOR) { dprint(2, "\t tune with OnePartChannel %d\n", tuneParam->major); } else if (IsOnePartChannelNumber(tuneParam->major)) { // À̰ÍÀº Raw major/minor·Î È£ÃâµÈ OnePartNumberÀÌ´Ù. º¯È¯ÀÌ ÇÊ¿äÇÏ´Ù. UINT16 nOnePartChannelNumber; nOnePartChannelNumber = ConvertToOnePartChannelNumber(tuneParam->major, tuneParam->minor); dprint(2, "\t change %d-%d to OnePartChannelNumber %d\n", tuneParam->major, tuneParam->minor, nOnePartChannelNumber); tuneParam->major = nOnePartChannelNumber; tuneParam->minor = ONE_PART_CHANNEL_INDICATOR; } //---------------------------- // ÀÌÁ¦ ä³ÎÀ» ã¾Æº»´Ù. // dprint(2, "\tspecified tuning: try tune %d-%d..\n", tuneParam->major, tuneParam->minor); for (i=0; ivct->numChannels; i++) { channel = &(ctx->vct->channel[i]); major = Dmc_GetMajorNumber(ctx->vct->is_cvct, channel); minor = Dmc_GetMinorNumber(ctx->vct->is_cvct, channel); if (major == tuneParam->major && minor == tuneParam->minor) { if (!channel->hidden || (tuneParam->flag & CTF_ShowHiddenChannelAlso)) { // hiddenµµ ¾Æ´Ï°í, hiddenÀÌ´õ¶óµµ ShowHidden flag°¡ ÀÖÀ¸¸é ó¸® °¡´ÉÇÔ.. bChannelFound = TRUE; break; } else { dprint(2, "!! channel found, but hidden! ignore it!\n"); bChannelFound = FALSE; } } } if (bChannelFound) { dprint(2, "\tchannel %d-%d found. (specified channel)\n", major, minor); status = doDmc_RfTuneByVctSubChannel(ctx, channel); if (status == statusCancelled) return statusCancelled; if (status == statusOK) { return statusOK; } returnStatus = status; } else { dprint(1, "!! %d-%d not found in CVCT\n", tuneParam->major, tuneParam->minor); returnStatus = statusChannelNotFound; } // specified tuning ¹æ¹ýÀ» »ç¿ëÇßÀ»¶§ tuning¿¡ ½ÇÆÐÇϸé // ÇöÀç ¿É¼Ç¿¡ µû¶ó¼­ retry¸¦ ÇÒ °ÍÀÎÁö ¾Æ´ÑÁö¸¦ °áÁ¤ÇÑ´Ù. // if ((tuneParam->flag & CTF_RetryOtherChannel)) { dprint(2, "\t retry other channel.. search from %d-%d\n", tuneParam->major, tuneParam->minor); currentMajorMinor = (tuneParam->major << 16UL) + (tuneParam->minor); // ÇöÀç ä³Î MM: retry¸¦ ÇÒ¶§ °Ë»öÀÇ ½ÃÀÛÁ¡ÀÌ µÈ´Ù. } else { // Àç½Ãµµ¸¦ ÇÏÁö ¾Ê´Â´Ù. ¿¡·¯¸¦ ¸®ÅÏÇÔ. // returnStatus´Â ÃÖÁ¾ ¿¡·¯ °ªÀ» º¸À¯Çϰí ÀÖ´Ù. // returnStatus : ChannelNotFound, VideoError, InvalidVCT µî. // return returnStatus; } label_retry_vct: //--------------------- // VCT retry mode // // Retry¸ðµåÀÏ °æ¿ì ¿¡·¯°¡ ¹ß»ýÇÏ¸é °è¼Ó ¹Ýº¹ÇÑ´Ù. // ´õÀÌ»ó ä³Î Á¤º¸°¡ ¾øÀ» ¶§ ±îÁö ¹Ýº¹. while (1) { // currentMM º¸´Ù "Å«" MM Áß¿¡¼­ ÃÖ¼Ò MMÀ» ã´Â´Ù. // ´Ü CTF_SkipNonFamilyChannel ¸ðµå¿¡¼­´Â Major°¡ °°Àº ä³Î·Î Á¦ÇÑÇÔ. // channel = doDmc_FindNextVctChannel(ctx->vct, currentMajorMinor, (tuneParam->flag & CTF_SkipNonFamilyChannel) ? TRUE : FALSE, (tuneParam->flag & CTF_ShowHiddenChannelAlso) ? FALSE : TRUE); if (channel == NULL) { // ´õÀÌ»ó ¿øÇϴ ä³Î ¾øÀ½. dprint(1, "\tNo more valid channel in VCT\n"); return statusChannelNotFound; } // ä³ÎÀÌ ¹ß°ßµÇ¾úÀ½. 'channel' pointer°¡ °¡¸®Å°´Â °÷¿¡ ¿øÇÏ´Â Á¤º¸°¡ ÀÖ´Ù. major = Dmc_GetMajorNumber(ctx->vct->is_cvct, channel); minor = Dmc_GetMinorNumber(ctx->vct->is_cvct, channel); currentMajorMinor = (major << 16UL) + minor; dprint(2, "\t found channel %d-%d (unspecified or retry channel)\n", major, minor); status = doDmc_RfTuneByVctSubChannel(ctx, channel); if (status == statusCancelled) return statusCancelled; if (status == statusOK) { return statusOK; } returnStatus = status; // ä³Î °Ë»ö¿¡ ½ÇÆÐ. ´ÙÀ½ ä³Î·Î Àç½Ãµµ Çϱâ Àü¿¡ retry ¸ðµåÀÎÁö ¾Æ´ÑÁö üũ¸¦ ÇÑ´Ù. if ((tuneParam->flag & CTF_RetryOtherChannel)) { dprint(2, "!! cannot start %d-%d in CVCT! try next channel..\n", major, minor); continue; } else { // retry ¸ðµå°¡ ¾Æ´Ï¹Ç·Î ±×³É ½ÇÆÐ·Î Á¾·á. returnStatus´Â ¸¶Áö¸· ¿¡·¯ °ªÀ» °¡Áö°í ÀÖ´Ù. dprint(2, "!! failed in starting %d-%d in CVCT! No retry, last err %d\n", major, minor, returnStatus); // returnStatus: InvalidVCT or VideoError µî.. return returnStatus; } } } STATUS doDmc_RfTuneByPsiSubChannel(ChannelTuneContext *ctx, int PmtPID, int program_number) { STATUS status; TuneParam *tuneParam = &ctx->param; DMC_VIDEO_CACHE cache; PidInfo psiPid; if (ctx->pmt) { dprint(2, "\tfree previous pmt\n"); FreePMT(ctx->pmt); ctx->pmt = NULL; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 0); #endif status = Dmc_GetPMT(Dmc_GetCurrentTsd(), PmtPID, program_number, &ctx->pmt, g_Timeout_PmtLoading*1000/1000, Dmc_CheckCancel); if (status == statusCancelled) return statusCancelled; else if (status) { dprint(1, "!! PMT load failed.\n"); return statusNoPSI; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 1); #endif // cafrii 070718 change // ³ªÁß¿¡ pid°¡ ¿ÏÀüÈ÷ °áÁ¤ µÈ ÈÄ¿¡ updateÇÔ. //ctx->pcrPid = ctx->vidPid = ctx->audPid = 0; status = Dmc_DecidePidInfo(ctx->pmt, NULL, &psiPid, 0); if (status == statusOK && psiPid.bValid) { dprint(2, "\t pid from pmt decided. pva %x %x %x, type va %d %d\n", psiPid.pcr, psiPid.video, psiPid.audio, psiPid.videoType, psiPid.audioType); } else { // ¿¡·¯ üũ´Â ¾Æ·¡¿¡¼­ audio pid ±îÁö °áÁ¤ µÈ ´ÙÀ½¿¡ ÇÏÀÚ. psiPid.pcr = psiPid.video = psiPid.audio = 0; } doDmc_SelectAudioStream(ctx->pmt, NULL, &(psiPid.audio), &(psiPid.audioType)); doDmc_SelectVideoStream(ctx->pmt, NULL, &(psiPid.video), &(psiPid.videoType)); if (psiPid.pcr == 0 || (psiPid.video == 0 && psiPid.audio == 0)) { dprint(1, "!! No valid video or audio pid..\n"); return statusInvalidPSI; } // cafrii 070718 add check. // ÀÌ Àü¿¡ ÀÌ¹Ì ½ÇÆÐÇÑ pid¶ó¸é ´Ù½Ã ½ÃµµÇÒ Çʿ䰡 ¾øÀ½. if (ctx->pid_tune_fail_count > 0 && DHL_OS_GetMsCount() - ctx->pid_tune_fail_time < 1000*20 && ctx->pcrPid == psiPid.pcr && ctx->vidPid == psiPid.video && ctx->audPid == psiPid.audio && (ctx->audType == 0 || ctx->audType == psiPid.audioType)) { dprint(0, "!! pid pvax (%x %x %x %x) already failed at %u ms before..\n", ctx->pcrPid, ctx->vidPid, ctx->audPid, ctx->audType, (DHL_OS_GetMsCount() - ctx->pid_tune_fail_time)*1000/1000); return statusInvalidPSI; } // ¸ðµç pid Á¤º¸ Áغñ ¿Ï·á. ctx->pcrPid = psiPid.pcr; ctx->vidPid = psiPid.video; ctx->audPid = psiPid.audio; ctx->audType = psiPid.audioType; ctx->vidType = psiPid.videoType; // cafrii 070412, add check pmt null if (ctx->pmt) { // cafrii 070201 add doDmc_NotifyPidInfo(ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->pmt->PID); } dprint(2, "\t vPid %x (t%d), aPid %x (t%d), pPid %x decoding start..\n", ctx->vidPid, ctx->vidType, ctx->audPid, ctx->audType, ctx->pcrPid); // arzhna, 100129 // doDmc_Notify()·Î app¿¡ notify, // app¿¡¼­ ó¸®ÇÏ¿© CARD¿¡ reportÇÑ´Ù. // ±âÁ¸ÀÇ ·çƾÀº »èÁ¦ { PSIChangeNotifyInfo pcni; memset(&pcni, 0, sizeof(pcni)); pcni.pmtchanged = TRUE; // This is PMT pcni.pmt = ctx->pmt; // new PMT // CableCard ¸ðµå¿¡¼­´Â PSI·Î¸¸ Æ©´×À» Çϴµ¥, // Æ©´×À» Çϱâ Àü¿¡ PMT report¸¦ ¼öÇàÇÑ´Ù. dprint(2, "\tReport CaPmt (prog# %d, pid %d,%d)\n", program_number, ctx->vidPid, ctx->audPid); // arzhna, 100203 // CA PMT¸¦ Àü´ÞÇϱâ À§ÇÑ callback È£Ãâ // DMC_NOTIFY_CaPmt event¸¦ º°µµ·Î ¸¸µé¾î ó¸® doDmc_Notify(DMC_NOTIFY_CaPmt, (UINT32)&pcni); } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0); #endif #if SUPPORT_DMW_VIDEO_CACHE // Ȥ½Ã cache Á¤º¸°¡ ÀÖ´ÂÁö load ÇØº»´Ù. cache = (DMC_VIDEO_CACHE)DHL_AV_LoadVideoFromCache(ctx->rf, ctx->program_number, ctx->vidPid, ctx->pcrPid); #else cache = (DMC_VIDEO_CACHE)NULL; #endif status = doDmc_StartDigital(ctx->vidPid, ctx->audPid, ctx->pcrPid, cache, ctx->vidType, ctx->audType); if (status == statusCancelled) { doDmc_ClearProgramInfo(); return statusCancelled; } if (status) { doDmc_ClearProgramInfo(); return status; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1); #endif doDmc_UpdateProgramInfoDigital(tuneParam->rf, tuneParam->type, TUNE_METHOD_ByPSI, 0, 0, program_number, ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->vidType, ctx->audType); doDmc_UpdatePsiInfo(ctx->pat, ctx->pmt); ctx->pat = NULL; ctx->pmt = NULL; return statusOK; } /*********** CmdRfTune ÇÔ¼ö¿¡¼­ Ç®¸®´Â Sub-fuctionÀÌ´Ù. NIMÀÇ frequency & demod ¼³Á¤Àº ¿Ï·áµÈ »óÅÂ.. PSI µ¥ÀÌÅÍ (PAT/PMTs)¸¦ ´Ù¿î·Îµå ¹Þ¾Æ ÂüÁ¶ÇÏ¿© tuneParam¿¡¼­ ÁöÁ¤ÇÑ ´ë·Î Æ©´×À» ½ÃµµÇÑ´Ù. ÇÁ·Î±×·¥À» ¼±ÅÃÇϴµ¥ tuneParam->progNumber¸¦ »ç¿ëÇÑ´Ù. ***********/ STATUS doDmc_RfTuneByPsi(ChannelTuneContext *ctx) { int i; STATUS status; STATUS returnStatus; int _second = 1000; int idx; // PAT index TuneParam *tuneParam = &ctx->param; if (Dmc_CheckCancel()) goto label_cancelled; dprint(1, "RfTuneByPsi: prognum %d\n", tuneParam->progNumber); // pat°¡ ¼ö½ÅÀÌ ¾ÈµÇ¾î ÀÖ´Â °æ¿ì¶ó¸é ´Ù½Ã ¼ö½ÅÇÑ´Ù. // if (ctx->pat == NULL) { dprint(2, "\tGet New PAT..\n"); status = Dmc_GetPAT(Dmc_GetCurrentTsd(), &ctx->pat, g_Timeout_PatLoading*_second/1000, Dmc_CheckCancel); if (status == statusCancelled) goto label_cancelled; else if (status) { dprint(1, "!! PAT load failed, %d\n", status); returnStatus = statusNoPSI; goto label_end_tune; } if (Dmc_CheckCancel()) goto label_cancelled; } dprint(2, "\tPAT found. total %d programs\n", ctx->pat->numPrograms); if (ctx->pat->numPrograms == 0 || ctx->pat->programs == NULL) { dprint(2, "!! invalid PSI.. no program!\n"); returnStatus = statusInvalidPSI; goto label_end_tune; } if (tuneParam->progNumber == 0) { // Unspecified tuning. // caller°¡ ƯÁ¤ ÇÁ·Î±×·¥ ¹øÈ£¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀº °æ¿ìÀÌ´Ù. // ÀÌ °æ¿ì ´ëÇ¥ ÇÁ·Î±×·¥ (Main program)À» ¼±ÅÃÇØ¾ß Çϴµ¥, // ÇöÀç´Â ±×³É ¸Ç óÀ½ °ÍÀ» »ç¿ëÇÑ´Ù. idx = 0; // ¸Ç óÀ½ ÇÁ·Î±×·¥ ºÎÅÍ °Ë»ö ½ÃÀÛÇÑ´Ù. tuneParam->progNumber = ctx->pat->programs[0].program_number; // ÀÌ·¸°Ô Çϸé Ç×»ó ¹Ýµå½Ã ã¾ÆÁö°Ô µÈ´Ù. dprint(2, "\t unspecified tuning. start from index 0\n"); } else { // find 'the program' whose program number is 'progNumber'. // if not found, we report error directly. // idx = -1; for (i=0; ipat->numPrograms; ++i) { if (ctx->pat->programs[i].program_number == tuneParam->progNumber) { idx = i; break; } } } if (idx < 0 || idx >= ctx->pat->numPrograms) { // cafrii 060628 bugfix!! i->idx dprint(1, "!! program number %d not found!\n", tuneParam->progNumber); returnStatus = statusChannelNotFound; goto label_end_tune; } //------ Program decoding loop ------------- // 'idx' is index of program table (PAT) // Retry flag°¡ ÀÖ´Â °æ¿ì¶ó¸é ¼º°ø ÇÒ ¶§±îÁö °è¼Ó retry¸¦ ÇÏ°Ô µÈ´Ù. // idxºÎÅÍ ½ÃÀÛÇØ¼­ ¸ðµç programÀ» ¸ðµÎ °Ë»çÇØº»´Ù. (wrap-around) // // cafrii 060727 bugfix // ¹«ÇÑ ·çÇÁ µµ´Â ¹®Á¦ ¼öÁ¤. cancelÀº µÇ´Ï±î Ä¡¸íÀûÀÌÁø ¾ÊÀ½. // i´Â Ƚ¼ö counting¸¸ Çϰí, idx·Î indexing. // //for (i=idx; ipat->numPrograms; i=(i+1)%ctx->pat->numPrograms) for (i=0; ipat->numPrograms; i++, idx=(idx+1)%ctx->pat->numPrograms) { dprint(2, "\ttry program [%d], pid %d, program number #%d\n", idx, ctx->pat->programs[idx].program_map_PID, ctx->pat->programs[idx].program_number); // MPEG_PAT status = doDmc_RfTuneByPsiSubChannel(ctx, ctx->pat->programs[idx].program_map_PID, ctx->pat->programs[idx].program_number); if (status == statusCancelled) goto label_cancelled; if (status == statusOK) { returnStatus = statusOK; goto label_end_tune; } // ±×¹ÛÀÇ ¸ðµç ¿¡·¯.. // flag¿¡ µû¶ó¼­ retryÀÇ ¿©ºÎ°¡ °áÁ¤µÈ´Ù. if (tuneParam->flag & CTF_RetryOtherProgram) { // ´ÙÀ½ program Àç½Ãµµ dprint(2, "\t! Psi tune err %d;.. retry other program..\n", status); continue; } else { returnStatus = statusInvalidPSI; goto label_end_tune; } } //--------- end for loop ----------- dprint(1, "!! No valid program! stop!\n"); returnStatus = statusInvalidPSI; goto label_end_tune; label_cancelled: returnStatus = statusCancelled; label_end_tune: return returnStatus; } STATUS doDmc_RfTuneSetTuner(ChannelTuneContext *ctx) { STATUS status = statusOK; UINT32 tickStartTunerSet; BOOL bLocked; // signal lock status int strength; // signal strength int _second = 1000; DHL_RESULT dhr; UINT32 cap; TuneParam *tuneParam = &ctx->param; // cafrii 060630 add, if already tuned to rf, skip! // modulation mode may be different.. // if ((tuneParam->flag & CTF_ForceSetTuner) == 0 && tuneParam->rf == DMW_HAL_GetCurrentRF() && DMW_HAL_DetectNIMChannel()) { //dprint(2, "\talready tuned to rf %d.. skip tune\n", ctx->rf); dprint(2, "\talready tuned to rf %d.. skip tuner setting\n", ctx->rf); // cafrii 070411 ¿ÀÇØ ¼ÒÁö°¡ ÀÖ´Â debug message ¹®±¸ ¼öÁ¤. return statusOK; } dhr = DHL_FE_GetDeviceInfo(DEFAULT_TUNER_ID, eDHL_FE_DEV_CAPABILITY_1, &cap); if (dhr != DHL_OK) { dprint(0, "!! dev cap query err %d\n", dhr); DHL_ASSERT(FALSE, ""); } tickStartTunerSet = DHL_OS_GetMsCount(); // µðÁöÅÐ modulationÀÎ °æ¿ì // if (tuneParam->type != Modulation_NTSC) { int nModeToTry = 0; ModulationType aModes[5]; int i, type, lock_timeout; int typeFirstTried; // cafrii 070227 add type = tuneParam->type; if (type == Modulation_CableAuto) { // Cable auto ¸ðµå´Â Analog ±îÁö Æ÷ÇÔÇÏ´Â °ÍÀÌÁö¸¸, // ±¸ÇöÀÌ º¹ÀâÇϹǷΠ±×³É QamAuto ¸ðµå·Î °£ÁÖ. type = Modulation_QAM; } if (tuneParam->flag & CTF_SkipQamModulation) { dprint(2, "\t Skip QAM mode..\n"); if (cap & eDHL_TUCAP_VSB) { aModes[nModeToTry++] = Modulation_8VSB; } else dprint(0, "!! FE not support VSB, but SkipQam mode requested\n"); } else if (type == Modulation_64QAM || type == Modulation_256QAM) { // arzhna, 100407 // QAM Mode°¡ ÁöÁ¤µÇ¾úÀ»¶§ ÁöÁ¤µÇÁö ¾ÊÀº ´Ù¸¥ modeµµ tryÇÏÁö ¾Êµµ·Ï auto¿Í ³ª´«´Ù. if ((cap & eDHL_TUCAP_QAMAUTO) && (tuneParam->flag & CTF_UseQamAutoMode)) { aModes[nModeToTry++] = Modulation_QAM; } else if (cap & eDHL_TUCAP_QAM) { // QAMAUTO´Â Áö¿øÇϸ鼭 QAMÀº Áö¿øÇÏÁö ¾Ê´Â FE°¡ ÀÖÀ¸¸é ¾ÈµÊ. // Âü°í·Î Capability¿¡´Â QAM64¿Í QAM256¿¡ ±¸ºÐÀÌ ¾ø´Ù. // µÎ QAM Áß¿¡ Çϳª¸¸ Áö¿øÇÏ´Â ±×·± demod´Â ¾øÀ» °Å¶ó°í °¡Á¤ÇÔ.. aModes[nModeToTry++] = (ModulationType)type; } else dprint(0, "!! FE not support QAM, but QAM requested. tucap 0x%x, req %d\n", cap, type); } else if (type == Modulation_QAM) { if ((cap & eDHL_TUCAP_QAMAUTO) && (tuneParam->flag & CTF_UseQamAutoMode)) { aModes[nModeToTry++] = Modulation_QAM; } else if (cap & eDHL_TUCAP_QAM) { // 64, 256 °¢°¢ ³ª´²¼­ µû·Î ½Ãµµ.. ¼ø¼­´Â ÀÏ´Ü callerÀÇ paramÀ» Á¸Áß.. // Qam auto ¸¦ request ÇÑ °æ¿ì¶ó¸é ¾îÂ¥ÇÇ qam auto°¡ Áö¿ø ¾ÈµÇ¹Ç·Î, ¾Æ¹«°Å³ª ¸ÕÀú.. if (type == Modulation_QAM) type = Modulation_256QAM; aModes[nModeToTry++] = (ModulationType)type; aModes[nModeToTry++] = (ModulationType)type == Modulation_64QAM ? Modulation_256QAM : Modulation_64QAM; } else dprint(0, "!! FE not support QAM, but QAM requested. tucap 0x%x, req %d\n", cap, type); } else if (type == Modulation_8VSB) { if (cap & eDHL_TUCAP_VSB) { aModes[nModeToTry++] = Modulation_8VSB; } else dprint(0, "!! FE not support VSB but VSB requested\n"); // Áö¿øÀÌ µÈ´Ù¸é Ãß°¡·Î QAM µµ ½Ãµµ.. if ((cap & eDHL_TUCAP_QAMAUTO) && (tuneParam->flag & CTF_UseQamAutoMode)) { aModes[nModeToTry++] = Modulation_QAM; } else if (cap & eDHL_TUCAP_QAM) { aModes[nModeToTry++] = Modulation_64QAM; aModes[nModeToTry++] = Modulation_256QAM; } } if (nModeToTry == 0) { dprint(0, "!! no mode to tune\n"); status = statusInvalidState; goto label_tune_end; } typeFirstTried = type; for (i=0; irf, type, ServiceTypeString(type), tuneParam->freqOffset, (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? 1 : 0); // cafrii 070710 use return value to check cancel status = DMW_HAL_TunerSetChannel(tuneParam->rf, (ModulationType)type, tuneParam->freqOffset, (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? FREQTUNE_SHORT_SEARCH : FREQTUNE_FIXED, Dmc_CheckCancel); if (status == statusCancelled) goto label_cancelled; if (gDmcTestSkipCheckSignalLock) { dprint(2, "\tskip signal detect..\n"); status = statusOK; goto label_tune_end; } if (status) goto label_tune_end; lock_timeout = g_Timeout_SignalLock; while (1) // wait until signal is locked. { bLocked = DMW_HAL_DetectNIMChannel(); if (bLocked) // ¸¸¾à lockÀÌ µÇ¾úÀ¸¸é ´õ ±â´Ù¸®Áö ¾Ê´Â´Ù. ¹Ù·Î break. break; if ((DHL_OS_GetMsCount() - tickStartTunerSet) > (unsigned int)lock_timeout*_second/1000) break; // time out! if (Dmc_CheckCancel()) goto label_cancelled; DHL_OS_Delay(_second/20); // give chance for other task to take CPU control. } if (Dmc_CheckCancel()) goto label_cancelled; if (bLocked && g_SignalThresholdForDigitalChannel) { strength = DMW_HAL_GetSignalStrength(); if (strength < g_SignalThresholdForDigitalChannel) { dprint(1, "!! signal locked, but strength too weak! %d < threshold %d. stop!\n", strength, g_SignalThresholdForDigitalChannel); bLocked = FALSE; // signal unlock°ú µ¿ÀÏÇÏ°Ô Ã³¸®ÇÑ´Ù. } } if (bLocked) { dprint(2, "\tsignal locked. %d ms\n", (DHL_OS_GetMsCount()-tickStartTunerSet)*1000/1000); goto label_tune_end; } // retry¸¦ ÇÏÁö ¾Ê´Â Á¶°Ç.. NTSCÀÎ °æ¿ì, Air ¸ðµåÀÎ °æ¿ì.. if (g_CurChannelType == ChannelType_Air) break; // ÀÌ typeÀ¸·Î ½ÇÆÐÇßÀ¸¹Ç·Î ´Ù¸¥ typeÀ¸·Î ´Ù½Ã ½ÃµµÇÑ´Ù. // } // end for modulation type // signal is not locked!! do error proccessing.. if (tuneParam->flag & CTF_RetryAnalogIfSignalUnlock) { dprint(2, "\t signal unlock. retry Analog mode..\n"); tuneParam->type = Modulation_NTSC; // force to NTSC.. if (tuneParam->rf) { dprint(2, "\tchanging tuner rf %d, type %d..\n", tuneParam->rf, 0); DMW_HAL_TunerSetChannel(tuneParam->rf, Modulation_NTSC, 0, FREQTUNE_SHORT_SEARCH, Dmc_CheckCancel); // offset zero, auto adjust TRUE } } else { dprint(1, "!! digital signal unlocked. stop!\n"); // cafrii 070227 add trick code // ¾îÂ¥ÇÇ ½ÇÆÐÇÑ °ÍÀε¥, ¸Ç óÀ½ tryÇÑ demodulation ¹æ¹ýÀ¸·Î ¹Ù²ã ³õÀÚ. // ´ÙÀ½ ¹ø¿¡ ÀÚµ¿ detect°¡ »¡¸® µÉ °ÍÀÓ. DMW_HAL_TunerSetChannel(tuneParam->rf, (ModulationType)typeFirstTried, tuneParam->freqOffset, (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? FREQTUNE_SHORT_SEARCH : FREQTUNE_FIXED, Dmc_CheckCancel); // °á°ú´Â üũÇÒ ÇÊ¿ä ¾øÀ½.. status = statusNoSignal; goto label_tune_end; } } else // NTSC tuning { if (tuneParam->rf) { dprint(2, "\tchanging tuner rf %d, type %d, offset %+d, autoFreq %d..\n", tuneParam->rf, tuneParam->type, tuneParam->freqOffset, (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? 1 : 0); DMW_HAL_TunerSetChannel(tuneParam->rf, Modulation_NTSC, tuneParam->freqOffset, //FREQTUNE_SHORT_SEARCH, (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? FREQTUNE_SHORT_SEARCH : FREQTUNE_FIXED, Dmc_CheckCancel); // offset zero, auto adjust TRUE } } label_tune_end: return status; label_cancelled: return statusCancelled; } STATUS doDmc_RfTuneByPidOnly(ChannelTuneContext *ctx) { STATUS status = statusOK; TuneParam *tuneParam = &ctx->param; DMC_VIDEO_CACHE cache; //---------------------------------------- // tune by PIDs.. // video pid, audio pid ¸ðµÎ 0À¸·Î ¼³Á¤Çؼ­ callÇϸé // pre-scan pid tuning ±â´ÉÀ» skipÇÏ´Â °ÍÀ¸·Î ¹Þ¾ÆµéÀδÙ. // if (tuneParam->pcrPid && (tuneParam->vidPid || tuneParam->audPid) && tuneParam->rf && tuneParam->progNumber) // prescan PID¿¡ ÀÇÇÑ Æ©´× ½Ãµµ. { dprint(2, " Try using prescan pids pvat %x %x %x vt %x at %x rf %d #%d..\n", tuneParam->pcrPid, tuneParam->vidPid, tuneParam->audPid, tuneParam->vidType, tuneParam->audType, tuneParam->rf, tuneParam->progNumber); ctx->vidPid = tuneParam->vidPid; ctx->audPid = tuneParam->audPid; ctx->pcrPid = tuneParam->pcrPid; ctx->audType = tuneParam->audType; ctx->vidType = tuneParam->vidType; #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0); #endif #if SUPPORT_DMW_VIDEO_CACHE // Ȥ½Ã cache Á¤º¸°¡ ÀÖ´ÂÁö load ÇØº»´Ù. cache = (DMC_VIDEO_CACHE)DHL_AV_LoadVideoFromCache(ctx->rf, ctx->program_number, ctx->vidPid, ctx->pcrPid); #else cache = (DMC_VIDEO_CACHE)NULL; #endif status = doDmc_StartDigital(ctx->vidPid, ctx->audPid, ctx->pcrPid, cache, ctx->vidType, ctx->audType); if (status == statusCancelled) { doDmc_ClearProgramInfo(); return statusCancelled; } else if (status) { //if (err != timeoutError) // timeout ¿ÜÀÇ ´Ù¸¥ ¿¡·¯¶ó¸é ¹®Á¦°¡ ÀÖ´Â °æ¿ìÀÌ´Ù. dprint(1, "!! pre-scan PID tune err %d. continue..\n", status); doDmc_ClearProgramInfo(); // prescan PID Á¤º¸¸¦ ¹«½ÃÇϰí Á¤»óÀûÀÎ ¹æ¹ýÀ¸·Î °è¼Ó ÁøÇàÇÑ´Ù. // cafrii 070718 add ctx->pid_tune_fail_count++; ctx->pid_tune_fail_time = DHL_OS_GetMsCount(); // ³ªÁß¿¡ ´Ù½Ã psip/psi·Î ½Ãµµ ÇÒ ¶§ pid°¡ µ¿ÀÏÇÏ¸é ´Ù½Ã ½ÃµµÇÒ Çʿ䰡 ¾ø¾î¼­. return status; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1); #endif // // ƯÁ¤ ±â´ÉÀ» À§Çؼ­ ÇöÀç Àç»ýÁßÀÎ programÀÇ program_number¸¦ ½±°Ô ¾Ë ¼ö ÀÖ´Â // ¹æ¹ýÀÌ ÇÊ¿äÇÏ´Ù. // ±×·¯±â À§Çؼ­ tuning¿¡ Á÷Á¢ »ç¿ëµÇÁö ¾Ê¾Ò´ø ÆÄ¶ó¹ÌÅ͵鵵 // ¸ðµÎ ProgramInfo¿¡ ±â·ÏÀ» ÇØ µÐ´Ù. // ´Ü ÀÌ Á¤º¸°¡ ÇöÀç ¼ö½ÅÁßÀÎ programÀÇ Á¤º¸¿Í µ¿ÀÏÇÏ´Ù´Â º¸ÀåÀº ÇÒ ¼ö ¾ø´Ù. // UCMÀÌ ¾ÆÁÖ ¿À·¡Àü¿¡ updateµÈ °æ¿ì¶ó¸é Ʋ¸± °¡´É¼ºµµ ÀÖ´Ù. // doDmc_UpdateProgramInfoDigital(tuneParam->rf, tuneParam->type, TUNE_METHOD_ByPIDs, tuneParam->major, tuneParam->minor, tuneParam->progNumber, tuneParam->vidPid, tuneParam->audPid, tuneParam->pcrPid, tuneParam->vidType, tuneParam->audType); // cafrii 040527 add comment // ÀÌ ¹æ½ÄÀÇ tuning¿¡¼­¸¸Å­Àº ÀÌ ½ÃÁ¡¿¡¼­ PTS ¼³Á¤À» ÇÒ ¼ö ¾ø´Ù. PMT¸¦ ¾ÆÁ÷ ¹ÞÁö ¸øÇ߱⠶§¹®. // PTS ¼³Á¤Àº ³ªÁß¿¡ PsiMonitor°¡ °¡µ¿µÈ ÈÄ PMT°¡ ¼ö½ÅµÇ¾úÀ»¶§ ÇÑ´Ù. // status = statusOK; } else status = statusInvalidArgument; return status; } void doDmc_ReturnTuneResult(void *pfnCompleted, STATUS status, UINT32 userparam, UINT32 additionalParam) { DMC_FN_TUNE_COMPLETED fn; fn = (DMC_FN_TUNE_COMPLETED) pfnCompleted; if (fn) { dprint(2, " return %s (%d, '%s') to caller..\n", status ? "error" : "success", status, DMW_CDB_ErrString(status)); fn(status, userparam, (AppRfTuneCallbackParam *) additionalParam); } else dprint(2, " return %s (%d, '%s') skipped.\n", status ? "error" : "success", status, DMW_CDB_ErrString(status)); } STATUS doDmc_RfTuneAnalog(ChannelTuneContext *ctx) { STATUS status; TuneParam *tuneParam = &ctx->param; CaptureParam capParam; #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0); #endif dprint(2, "\tstart analog video..\n"); // arzhna, 100129 // doDmc_Notify()·Î app¿¡ notify, // app¿¡¼­ ó¸®ÇÏ¿© CARD¿¡ reportÇÑ´Ù. // ±âÁ¸ÀÇ ·çƾÀº »èÁ¦ // // DMC_NOTIFY_CaPmt event¸¦ º°µµ·Î ¸¸µé¾î ó¸® dprint(2, "\t Report CaPmt (NULL)\n"); doDmc_Notify(DMC_NOTIFY_CaPmt, (UINT32)NULL); memset(&capParam, 0, sizeof(capParam)); capParam.input_video = eDHL_CAP_NTSC0_VIDEO; capParam.input_audio = eDHL_CAP_NTSC0_AUDIO; status = doDmc_StartAnalog(&capParam); if (status) { status = statusAnalogError; dprint(0, "!! err in start analog, err %d. stop!\n", status); } else { doDmc_UpdateProgramInfoAnalog(tuneParam->rf, eDHL_CAP_NTSC0_VIDEO, eDHL_CAP_NTSC0_AUDIO); status = statusOK; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1); #endif return status; } STATUS doDmc_CmdRfTune(DmcMessage *pmsg) { STATUS status; ChannelTuneContext context, *ctx = &context; TuneParam *tuneParam; // ÆÄ¶ó¹ÌÅÍ·Î °Ç³×Áö´Â tuneParamÀº »ç¿ë ÈÄ OS_Free½ÃÄÑ¾ß ÇÑ´Ù. dprint(1, "cmdRfTune: cid %d\n", pmsg->cancelId); if (pmsg->param == 0) { dprint(0, " !! tuneParam NULL! stop! no callback!!\n"); return statusInvalidArgument; } #if USE_PERF_MON if (gDmcPMTune == 0) { gDmcPMTune = DHL_PerfMonInit("DmcTune", 1); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_TOTAL, PM_EV_Name[PM_EV_TUNE_TOTAL]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_STOP, PM_EV_Name[PM_EV_TUNE_STOP]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_LOCK, PM_EV_Name[PM_EV_TUNE_LOCK]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_PSIP_LOAD, PM_EV_Name[PM_EV_TUNE_PSIP_LOAD]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, PM_EV_Name[PM_EV_TUNE_PSI_LOAD]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_AV_START, PM_EV_Name[PM_EV_TUNE_AV_START]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_VIDEO_START, PM_EV_Name[PM_EV_TUNE_VIDEO_START]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_AUDIO_START, PM_EV_Name[PM_EV_TUNE_AUDIO_START]); DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_CALLBACK, PM_EV_Name[PM_EV_TUNE_CALLBACK]); } #endif #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_TOTAL, 0); #endif memset(ctx, 0, sizeof(ChannelTuneContext)); (ctx->param) = *(TuneParam *)pmsg->param; // tune param backup ctx->rf = ctx->param.rf; ctx->program_number = ctx->param.progNumber; Dmc_ParamHeapDeallocator(pmsg->param); tuneParam = &ctx->param; #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_STOP, 0); #endif // ±âÁ¸ ºñµð¿À°¡ µ¿ÀÛÁßÀÌ¸é ´Ý´Â´Ù. doDmc_Stop(); #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_STOP, 1); #endif if (Dmc_CheckCancel()) goto label_cancelled; //---------------------------------------- // #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_LOCK, 0); #endif #if 0 // cafrii 060630 delete if (! tuneParam->tuneRequired) { dprint(2, "\tskip tuner HAL tuning..\n"); } else #endif { status = doDmc_RfTuneSetTuner(ctx); if (status) goto label_end_tune; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_LOCK, 1); #endif if (tuneParam->flag & CTF_TunerSetOnly) { // Æ©³Ê ¼³Á¤¸¸ ¼öÇàÇ϶ó´Â ¿É¼ÇÀÌ´Ù. // ÀÌ ±â´ÉÀº POD ¸ðµå¿¡¼­ ChannelForceTune request°¡ ¿Ã °æ¿ì¿¡ »ç¿ëµÈ´Ù. // dprint(1, " TunerSetOnly mode..\n"); status = statusOK; goto label_end_tune; } if (Dmc_CheckCancel()) goto label_cancelled; //---------------------------------------- // NTSC tuning if (tuneParam->type == Modulation_NTSC) { status = doDmc_RfTuneAnalog(ctx); goto label_end_tune; // ¾Æ³¯·Î±× ä³ÎÀº À̰ÍÀ¸·Î ¸ðµç ÀÛ¾÷ÀÌ ³¡³­´Ù. } Demux_tsdStart(Dmc_GetCurrentTsd(), 0); //---------------------------------------- // cafrii 041201 add // POD mode ¿¡¼­´Â PID tuningÀ» »ç¿ëÇϱⰡ °ï¶õÇÔ. // ¸ÕÀú PMT¸¦ ¼ö½ÅÇÑ ´ÙÀ½ CA_PMT¸¦ POD¿¡ report¸¦ ÇÑ ´ÙÀ½¿¡ Æ©´×ÇØ¾ß Çϱ⠶§¹®. // { // bugfix. callback ¹Ì ±¸Çö½Ã µðÆúÆ®´Â normal mode. PodStatusParam status; status.isPodInserted = FALSE; doDmc_Notify(DMC_NOTIFY_IsPodInserted, (UINT32)&status); if (status.isPodInserted) { dprint(2, " cable card active mode.. force PSI tuning\n"); goto label_try_psi; } } //---------------------------------------- // tune by PIDs.. if (tuneParam->flag & CTF_SkipPrescanPidInfo) { dprint(3, " skip prescan pids by user flag\n"); } else { status = doDmc_RfTuneByPidOnly(ctx); if (status == statusCancelled) goto label_cancelled; else if (status == statusOK) { doDmc_StartFinalPsiMonitor(TRUE); goto label_end_tune; } } //---------------------------------------- // Å×À̺íÀ» ¼ö½ÅÇÑ´Ù. TVCT, CVCT, PAT ¸ðµÎ ¼ö½Å. // // cafrii 070427 move position // psi only mode ¿¡¼­´Â vct¸¦ ¹Þ¾Æµµ »ç¿ëÇÏÁöµµ ¾ÊÀ¸¹Ç·Î // °¢ÀÚ ÇÊ¿äÇÑ ¶§¿¡ pat/pmt¸¦ ¹Þµµ·Ï ÇÑ´Ù. // if ((tuneParam->flag & CTF_Mask_Tuning) == CTF_PSIOnly) { dprint(2, "\tPSI only modes..\n"); goto label_try_psi; } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSIP_LOAD, 0); #endif status = doDmc_DownloadTables(ctx); if (status == statusCancelled) goto label_cancelled; #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSIP_LOAD, 1); #endif if (ctx->vct) { // ¼ö½ÅµÈ VCT¸¦ ÀÌ¿ëÇÏ¿© Æ©´×À» ½ÃµµÇÑ´Ù. // status = doDmc_RfTuneByVct(ctx); if (status == statusCancelled) { goto label_cancelled; } else if (status == statusOK) { doDmc_StartFinalPsiMonitor(TRUE); goto label_end_tune; } } // »ç¿ë °¡´ÉÇÑ Tuning Mode // CTF_VCTOnly or CTR_Automatic or CTR_SemiAutomatic. // // VCTOnly´Â VCT·Î ó¸®ÇÏ´Â µµÁß ¿¡·¯°¡ ¹ß»ýÇÏ¸é ±×³É ¿¡·¯·Î Áß´Ü. // Automatic/SemiAutomaticÀÎ °æ¿ì´Â VCT¿¡¼­ ¿¡·¯°¡ ³ª¸é PSI·Î ³Ñ¾î°¡¼­ °è¼Ó ÁøÇà. // if ((tuneParam->flag & CTF_Mask_Tuning) == CTF_VCTOnly) { // returnStatus °ªÀº ÀÌ¹Ì Àû´çÇÑ °ªÀ» °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù. // ÀÌ °ªÀÌ ±×´ë·Î callback¿¡ ¸®ÅϵȴÙ. goto label_end_tune; } if ((tuneParam->flag & CTF_Mask_Tuning) == CTF_SemiAutomatic) { // semi automatic ¸ðµå¶ó¸é ÇöÀç ¾î¶² ¿¡·¯°ªÀ» °¡Áö°í ÀÖ´À³Ä¿¡ µû¶ó // ºÐ±â°¡ °áÁ¤µÈ´Ù. // ¶ÇÇÑ ÀÌ ¸ðµå´Â retry Ç÷¡±×¿Í ÇÔ²² »ç¿ëµÇ¸é Àǹ̰¡ ¾ø´Ù. ¹«½ÃµÈ´Ù. if ((tuneParam->flag & CTF_RetryOtherChannel) == 0 && (status == statusVideoError)) { // ÀÌ¹Ì video decodingÀÌ ½ÃµµµÈ »óÅÂÀ̹ǷΠ´õÀÌ»ó ½ÃµµÇÏÁö ¾Ê´Â´Ù. dprint(2, "\tsemiAuto, noRetry mode with videoError status. skip PSI mode\n"); goto label_end_tune; } } label_try_psi: //------------------------------------------------------------ // PAT, PMT¸¦ ÀÌ¿ëÇÏ¿© Æ©´×À» ½ÃµµÇÑ´Ù. status = doDmc_RfTuneByPsi(ctx); if (status == statusCancelled) { goto label_cancelled; } else if (status == statusOK) { doDmc_StartFinalPsiMonitor(TRUE); } goto label_end_tune; label_cancelled: status = statusCancelled; goto label_end_tune; label_end_tune: //------------------------------------------------------------ // cafrii 060802 add // statusCancelled ¸Þ½ÃÁö Àü´ÞÀº ¾ÆÁÖ Áß¿äÇÏ´Ù. // ¸ðµç result °ª¿¡ ¿ì¼±Çؼ­ Àü´ÞµÇ¾î¾ß ÇÑ´Ù. // ÇöÀç ¸ðµç tuning °ü·Ã ÀÛ¾÷ÀÌ °ÅÀÇ ´Ù ¼º°øÇß´Ù ÇÏ´õ¶óµµ // user°¡ cancelÀ» ¿øÇϸé statusCancelled¸¦ ³Ñ°ÜÁà¾ß ÇÑ´Ù. // if (status != statusCancelled) { if (Dmc_CheckCancel()) { dprint(0, "!! tuning cancelled at final stage. status %d -> %d\n", status, statusCancelled); status = statusCancelled; } } if (1) { AppRfTuneCallbackParam returnParam; ProgramAVInfo *av; memset(&returnParam, 0, sizeof(AppRfTuneCallbackParam)); av = Dmc_LockAVMutex(); returnParam.program = av; returnParam.tuneParam = tuneParam; returnParam.vct = ctx->vct; returnParam.pat = av->pat ? av->pat : ctx->pat; returnParam.pmt = av->pmt ? av->pmt : ctx->pmt; // TuningÀ» Çϸ鼭 PAT/PMT°¡ Áغñ°¡ µÇ¾ú´Ù¸é av->pat/pmt¿¡ ÀúÀåµÇ¾î ÀÖÀ¸¹Ç·Î // ±× °ªÀ» ³Ñ°ÜÁØ´Ù. // Æ©´× Áß¿¡ ½ÇÆÐÇÑ °æ¿ì¶ó¸é ±×³É ctx ³»¿¡ ³²¾ÆÀÖÀ» °ÍÀÌ´Ù. // cafrii 060804 add av->userParam = pmsg->userParam; // tune callbackÀÇ userparamÀ» ±â¾ïÇØ µÎ°í // psi changed notification¿¡¼­ ÀÌ parameter¸¦ ³Ñ°ÜÁÖÀÚ. #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_CALLBACK, 0); #endif doDmc_ReturnTuneResult((void *)pmsg->pfnCompleted, status, pmsg->userParam, (UINT32)&returnParam); #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_CALLBACK, 1); #endif Dmc_UnlockAVMutex(); } if (ctx->vct) { dprint(2, "\t free ctx->vct 0x%x\n", ctx->vct); FreeAtscTable(ctx->vct); } // pat, pmt°¡ dmc_pat/dmc_pmt·Î µî·ÏµÇ´Â °ÍÀº StartDigital ¿¡¼­ active ON µÇ´Â ¼ø°£ÀÌ´Ù. // tuneParam¿¡ pat/pmt°¡ ³²¾ÆÀÖ´Â °æ¿ì´Â tuning¿¡ ½ÇÆÐÇÑ °æ¿ìÀ϶§ÀÌ´Ù. // if (ctx->pat) { dprint(2, "\t free ctx->pat 0x%x\n", ctx->pat); FreePAT(ctx->pat); } if (ctx->pmt) { dprint(2, "\t free ctx->pmt 0x%x\n", ctx->pmt); FreePMT(ctx->pmt); } #if USE_PERF_MON DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_TOTAL, 1); #endif return status; } // doDmc_CmdRfTune #if COMMENT ________(){} #endif #if DMW_REGISTER_DEBUG_SYMBOL static DHL_SymbolTable symbols[] = { //---- functions //---- vars DHL_VAR_SYM_ENTRY(g_SignalThresholdForDigitalChannel), DHL_VAR_SYM_ENTRY(gDmcTestSkipVctDownload), }; #endif void RegisterChannelTuneSymbols(void) { #if DMW_REGISTER_DEBUG_SYMBOL DHL_DBG_RegisterSymbols(symbols, DHL_NUMSYMBOLS(symbols)); #endif }