source: svn/newcon3bcm2_21bu/dst/dmw/src/Channel/DMW_ChannelTune.c @ 22

Last change on this file since 22 was 22, checked in by phkim, 11 years ago
  1. phkim
  2. newcon3sk 를 kctv 로 브랜치 함
  • Property svn:executable set to *
File size: 50.2 KB
Line 
1/*
2        DMW_ChannelTune.c
3       
4       
5       
6*/
7
8
9
10#include "DMW_Platform.h"
11
12
13
14
15#include "DHL_DBG.h"
16#define Demux_tsdStart(a,b)
17
18#include "DMW_Config.h"
19#include "DMW_DebugUtil.h"
20#include "DMW_Status.h"
21
22#include "DMW_Channel.h"
23#include "DMW_ChannelUtil.h"
24#include "DMW_ChannelDemux.h"
25
26#include "DMW_ChannelPM.h" // Performance monitor
27
28//#include <string.h>
29
30
31DHL_MODULE("$dmc", 1);
32
33
34
35
36
37#if USE_PERF_MON
38
39static char *PM_EV_Name[] =
40{
41        "Total", // total elapsed time for tuning
42        "Stop",  // previous video stop
43        "Lock",  // tuner/demod lock
44        "PSIP",  // download psip
45        "PSI",   // download psi
46        "AV",    // video+audio
47        "Video", // video context creation
48        "Audio", // audio start and detect
49        "Callback", // tune complete callback
50};
51
52DHL_PM_HANDLE gDmcPMTune;
53
54#endif
55
56
57
58
59
60// Config Param: [0 ~ 100]  Tuner µå¶óÀ̹öÀÇ ½ÅÈ£¼¼±â ¸®ÅÏ ¹üÀ§ ÁöÁ¤
61//
62// µðÁöÅРä³Î¿¡¼­ Signal strengh threshold
63//
64// channel scanÀ» ÁøÇàÇϱâ À§ÇØ ÇÊ¿äÇÑ ÃÖÀú ½ÅÈ£ ¼¼±â.
65// ¼³·É lockÀÌ µÇ¾ú´õ¶óµµ ÀÌ ½ÅÈ£¼¼±â¸¸Å­ ÀâÈ÷Áö ¾ÊÀ¸¸é ä³Î LockÀÌ ¾ÈµÈ °ÍÀ¸·Î
66// °£ÁÖÇÑ´Ù. ÀÌ °ªÀº µðÁöÅРä³Î¿¡¼­¸¸ Àû¿ëµÈ´Ù. 
67// 0Àº Ưº°ÇÑ Àǹ̷μ­, ½ÅÈ£¼¼±â¿¡ ¹«°üÇÏ°Ô lock ¿©ºÎ·Î¸¸ ÆÇ´ÜÇÏ¿© ÁøÇàÇϵµ·Ï
68// ÇÑ´Ù.
69//
70int g_SignalThresholdForDigitalChannel = 0;
71
72
73//
74// Config Param: TRUE or FALSE
75//
76// Å×½ºÆ® º¯¼ö
77//
78// TRUEÀ̸é tuningÇÒ ¶§ signal lock üũ¸¦ ÇÏÁö ¾Ê´Â´Ù.
79// signal °ü·ÃµÈ Å×½ºÆ®¸¦ ÇÒ ¶§ »ç¿ë.
80//
81int gDmcTestSkipCheckSignalLock = 0;
82
83
84
85//
86// Config Param: TRUE or FALSE
87//
88// Å×½ºÆ® º¯¼ö
89//
90// TRUEÀ̸é tuningÇÒ ¶§ VCT¸¦ ¼ö½ÅÇÏÁö ¸øÇÑ °Í ó·³ µ¿ÀÛÇÑ´Ù.
91//
92// cafrii 060628 addd
93//
94int gDmcTestSkipVctDownload = 0;
95
96
97
98// TuneParam
99//   1. AV Decoding¿¡ ÇÊ¿äÇÑ Request Parameter. RfTuneÀÇ ÇÔ¼ö ÀÎÀÚ·Î applicationÀÌ Á¦°ø.
100//   2. TuneCallbackÀ» ÅëÇØ¼­ tuningÀÇ °á°ú°¡ ³Ñ°ÜÁú¶§ Dmc code°¡ app·Î Á¦°øÇÔ.
101
102typedef struct
103{
104        TuneParam param;
105
106        int rf, program_number; // ÀÌ Á¤º¸´Â video cache indicator·Î »ç¿ëµÈ´Ù.
107       
108        // Video/Audio decoding..
109        UINT32 pcrPid, vidPid, audPid;
110
111        // cafrii 070718 add
112        BOOL pid_tune_fail_count;
113        UINT32 pid_tune_fail_time;
114
115        MPEG_PAT *pat;
116        MPEG_PMT *pmt;
117        xvctPtr_t vct;
118       
119        VideoStreamDescriptor *vidDesc;
120       
121        tDHL_VideoCodingType  vidType; /* add for avc */
122       
123        tDHL_AudioCodingType  audType;
124
125} ChannelTuneContext;
126
127
128
129
130
131
132#if COMMENT
133_______DMC_CORE3________(){}
134#endif
135
136
137//-------------------------------------------------------
138
139
140xvctChannelPtr_t doDmc_FindNextVctChannel(xvctPtr_t vctPtr, UINT32 currentMajorMinor, 
141                                        BOOL bSkipNonFamilyChannel, BOOL bSkipHiddenChannel)
142{
143        int i;
144        xvctChannelPtr_t channel;
145        UINT32 minMajorMinor, tmpMajorMinor;
146        int minIndex;
147        UINT16 major, minor;
148       
149        if (!vctPtr) return NULL;
150       
151        // ÁöÁ¤µÈ ä³Î ¹øÈ£ (currentMajorMinor) ºÎÅÍ °Ë»ö.
152        //
153
154        // currentMM º¸´Ù Å« MM Áß¿¡¼­ ÃÖ¼Ò MMÀ» ã´Â´Ù.
155        // ´Ü CTF_RetryOtherFamilyChannel ¸ðµå¿¡¼­´Â Major°¡ °°Àº ä³Î·Î Á¦ÇÑÇÔ.
156        //
157        //dprint(2, " find minimum minor..\n");
158        minMajorMinor = (UINT32)(-1);
159        minIndex = -1;
160       
161        for (i=0; i<vctPtr->numChannels; i++)
162        {
163                channel = &vctPtr->channel[i];
164                if (channel == NULL) continue;
165
166                major = Dmc_GetMajorNumber(vctPtr->is_cvct, channel);
167                minor = Dmc_GetMinorNumber(vctPtr->is_cvct, channel);
168
169                if (bSkipHiddenChannel && channel->hidden)
170                        continue;
171
172                if (bSkipNonFamilyChannel && (currentMajorMinor >> 16)) {
173                        // FamilyChannel ¸ðµå: ¹ß°ßµÇ¾ú´õ¶óµµ Major°¡ ²À ÀÏÄ¡ÇØ¾ß ÇÑ´Ù.
174                        //
175                        if ((currentMajorMinor >> 16) != major) {
176                                dprint(2, "!! skip non-family channel %d,%d\n", major, minor);
177                                continue;
178                        }
179                }
180
181                //dprint(2, "       [%d] %d-%d\n", i, major, minor);
182                tmpMajorMinor = (major<<16UL) + minor;
183                if (currentMajorMinor >= tmpMajorMinor) continue; // ´õ ÀÛÀº ä³Î¹øÈ£. skip!
184
185                if (minMajorMinor > tmpMajorMinor) {
186                        minMajorMinor = tmpMajorMinor;
187                        minIndex = i;
188                }
189        }
190
191        if (minIndex < 0)  // ´õÀÌ»ó ¾øÀ½.
192                return NULL;
193               
194        channel = &vctPtr->channel[minIndex];
195       
196        return channel;
197}
198
199
200
201// cafrii 060710 add
202//
203//  vctÀÇ program number¿¡ ÇØ´çÇÏ´Â ÇÁ·Î±×·¥ÀÌ PAT¿¡ ¾ø´Â °æ¿ì,
204//  vctÀÇ program numberÀÇ PMT°¡ ¼ö½ÅÀÌ ¾ÈµÇ´Â °æ¿ì,
205//  vctÀÇ program number Á¤º¸°¡ À߸øµÈ °ÍÀ¸·Î °¡Á¤ÇÏ°í º¹±¸¸¦ ¼öÇàÇÑ´Ù.
206//  µî·ÏµÈ ¸ðµç PMT¸¦ ¼ö½ÅÇØ¼­ °¡Àå ºñ½ÁÇÑ PMTÀÇ program number·Î ±³Ã¼ÇÑ´Ù.
207//
208//  [IN] xvctChannelPtr_t channel : º¹±¸ÇÒ vct channel.
209//       pat
210//
211//  [OUT] »õ·Ó°Ô ¼ö½Å µÈ pmt
212//
213STATUS doDmc_RecoverVctProgramNumber(ChannelTuneContext *ctx, xvctChannelPtr_t channel)
214{
215        STATUS status;
216        int k;
217        int _second = 1000;
218
219        MPEG_PAT *pat = ctx->pat;
220        MPEG_PMT *pmt = NULL;
221
222        PidInfo pid1, pid2;
223
224        if (channel == NULL)
225                return statusInvalidArgument;
226
227        dprint(2, "doDmc_RecoverVctProgramNumber(#%d):\n", channel->program_number);
228
229        if (ctx->pmt) {
230                dprint(2, "\tfree previous PMT.. program num %d\n", ctx->pmt->program_number);
231                FreePMT(ctx->pmt);
232                ctx->pmt = NULL;
233        }
234
235        if (ctx->pat == NULL)
236                return statusInvalidPSI;
237       
238        // PAT ¼ö½ÅÀ» ´õÀÌ»ó ½ÃµµÇÏÁö ¾Ê´Â´Ù.
239        // ÀÌ ÇÔ¼ö°¡ ºÒ¸®´Â ´Ü°è¶ó¸é ÀÌ¹Ì ¸î ¹ø PAT ¼ö½Å¿¡ ½ÇÆÐÇÑ °æ¿ìÀÏ °ÍÀÓ.
240        //
241
242        if (pat->numPrograms == 0 || pat->programs == NULL) {
243                dprint(1, "!! invalid PSI.. no program in pat?\n");
244                status = statusInvalidPSI;
245                goto label_end_function;
246        }
247
248        //--------------------
249        //  VCT processing
250       
251        memset(&pid1, 0, sizeof(pid1));
252
253        status = Dmc_GetInfoFromVctDesc(channel->descriptors, 
254                                channel->descriptor_length, &pid1, NULL);
255
256        if (status) {
257                dprint(2, "!! vct pid info invalid. cannot recover\n");
258                return statusInvalidVCT;
259        }
260
261        //--------------------
262        //  PMT processing
263
264        dprint(2, "  load %d pmts\n", pat->numPrograms);
265       
266        for (k=0; k<pat->numPrograms; k++)
267        {
268                dprint(2, "    [%d] get pmt #%d, pid %x\n", k, 
269                        pat->programs[k].program_number, pat->programs[k].program_map_PID);
270
271                if (pmt) {
272                        FreePMT(pmt);
273                        pmt = NULL;  // cafrii 060719 bugfix!! PR DS075 fix
274                }
275                status = Dmc_GetPMT(Dmc_GetCurrentTsd(), pat->programs[k].program_map_PID,
276                                                pat->programs[k].program_number, &pmt, 
277                                                g_Timeout_PmtLoading*_second/1000, Dmc_CheckCancel);
278
279                if (status == statusCancelled) goto label_cancelled;
280
281                else if (status) {
282                        dprint(2, "\t !! PMT[%d] load failed, %d\n", k, status);
283                        continue;
284                }
285
286                // pmtÀÇ pid Á¤º¸¿Í, vctÀÇ pid Á¤º¸°¡ ÀÏÄ¡ÇÏ¸é ¼­·Î °°Àº programÀ¸·Î º¸°í
287                // vctÀÇ program number¸¦ ¼öÁ¤ÇÏÀÚ!
288
289                status = Dmc_GetPidInfoFromPMT(pmt, &pid2);
290
291                if (status) {
292                        dprint(2, "\t PMT[%d] pid info err %d\n", k, status);
293                        continue;
294                }
295
296                if (pid1.pcr == pid2.pcr &&
297                        pid1.video == pid2.video &&
298                        pid1.audio == pid2.audio)
299                {
300                        dprint(2, "\tcorrect pmt found. recover #%d -> #%d\n", 
301                                        channel->program_number, pmt->program_number);
302                        channel->program_number = pmt->program_number;
303
304                        if (ctx->pmt)
305                                FreePMT(ctx->pmt);
306                       
307                        ctx->pmt = pmt;
308                        pmt = NULL;
309
310                        goto label_end_function;
311                }
312        }
313
314        dprint(2, "\tproper pmt not found.\n");
315        goto label_end_function;
316       
317label_cancelled:
318        status = statusCancelled;
319       
320label_end_function:
321
322        if (pmt)
323                FreePMT(pmt);
324
325        return status;
326
327}
328
329
330// 
331//  ÇØ´ç program number¿¡ ÇØ´çÇÏ´Â PAT/PMT¸¦ ¼ö½ÅÇÑ´Ù.
332//    statusOK
333//    statusInvalidPSI
334//    statusNoPSI
335//    statusCancelled
336//
337STATUS doDmc_GetPmtByProgramNumber(ChannelTuneContext *ctx, UINT16 program_number)
338{
339        return Dmc_GetPmtByProgramNumber(&(ctx->pat), &(ctx->pmt), 
340                                        program_number, doDmc_CheckCancel);
341}
342
343
344
345// cafrii 070201 add
346void doDmc_NotifyPidInfo(UINT16 uVidPid, UINT16 uAudPid, UINT16 uPcrPid, UINT16 uPmtPid)
347{
348        DecodingPidReadyParam dprp;
349       
350        dprp.vid_pid = uVidPid;
351        dprp.aud_pid = uAudPid;
352        dprp.pcr_pid = uPcrPid;
353        dprp.pmt_pid = uPmtPid;
354       
355        doDmc_Notify(DMW_NOTIFY_DecodingPidReady, (UINT32) &dprp);     
356}
357
358
359
360//  doDmc_DownloadTables
361//
362//  Digital tuning ¿¡¼­ È£ÃâµÇ¾î TVCT, CVCT, PAT¸¦ µ¿½Ã¿¡ ¼ö½ÅÇÑ´Ù.
363//  ¼ö½ÅµÈ VCTµéÀº xvct·Î ÅëÇÕµÇ¾î °ü¸®µÈ´Ù.
364//
365//  ¸®ÅϰªÀº statusOK ¾Æ´Ï¸é statusCancelled ¸¸ °¡´ÉÇÏ´Ù.
366//  ÀÚ¼¼ÇÑ ¿¡·¯ »óȲÀº ¸®ÅϵÇÁö ¾ÊÀ¸¸ç, °á°ú pointer¸¦ º¸°í ÆÇ´ÜÇØ¾ß ÇÑ´Ù.
367//
368STATUS doDmc_DownloadTables(ChannelTuneContext *ctx)
369{
370        tvctPtr_t tvct = NULL;
371        cvctPtr_t cvct = NULL;
372       
373        STATUS status;
374        int _second = 1000;
375       
376        //------------
377       
378        dprint(1, "downloading tables..\n");
379
380        //-------------
381        // ÀÌ¹Ì TuneParam¿¡ ¹º°¡ ¹Þ¾ÆÁø°Ô ÀÖÀ¸¸é »èÁ¦ÇÑ´Ù.
382        // ÀÌ ÇÔ¼ö´Â RfTune Ãʱ⿡ ºÒ¸®±â ¶§¹®¿¡ ¾î¶°ÇÑ tableµµ ¹Þ¾ÆÁ®ÀÖÀ¸¸é ¾ÈµÈ´Ù.
383       
384        ctx->vct = NULL;
385        ctx->pat = NULL;
386       
387        //------ Table ·Îµù (synchornous ¹æ½Ä)
388
389        status = Dmc_GetVctAndPat(Dmc_GetCurrentTsd(), 
390                                        &tvct, &cvct,
391                                        &ctx->pat, 
392                                        g_Timeout_VctLoading*_second/1000, Dmc_CheckCancel);
393        //
394        // pat¿Í (tvct³ª cvct) µÑ Áß Çϳª¸¸ ¼ö½ÅµÇ¸é ÀÏ´Ü ¸®ÅÏÇÑ´Ù.
395        // ¹°·Ð µ¿½Ã¿¡ µÑ ´Ù ¼ö½ÅµÉ °¡´É¼ºµµ ÀÖ´Ù.
396
397        if (status == statusCancelled)
398                return statusCancelled;
399
400        // TVCT, CVCT°¡ µÑ ´Ù ¼ö½ÅÀÌ ¾ÈµÉ ¼öµµ ÀÖ´Ù. ¼³·É PAT´Â ¼ö½ÅÀÌ µÇ¾ú´Ù°í ÇÏ´õ¶óµµ
401        // ÁøÇàÇÏÁö´Â ¾Êµµ·Ï ÇÏÀÚ.
402        //
403        if (tvct == NULL && cvct == NULL) {
404                dprint(1, "!! No VCTs found\n");
405                return statusNoVCT;  // ¸®ÅϰªÀº º° Àǹ̰¡ ¾ø´Ù.
406        }
407       
408        // Antenna ¸ðµå¿¡¼­´Â CVCT°¡ ¼ö½ÅÀÌ µÇ¾ú¾îµµ À̰ÍÀ» »ç¿ëÇÏÁö ¾Êµµ·Ï ÇÑ´Ù.
409       
410        if (cvct && g_CurChannelType == ChannelType_Cable)
411        {
412                status = Dmc_TranslateCvct(cvct, &(ctx->vct));
413                if (status == statusOK)
414                        dprint(2, "\tCVCT found. total %d channels\n", ctx->vct->numChannels);
415                else {
416                        dprint(0, "!! cvct->vct err %d\n", status);
417                        ctx->vct = NULL;
418                }
419        }
420        else if (tvct)
421        {
422                status = Dmc_TranslateTvct(tvct, &(ctx->vct));
423                if (status == statusOK)
424                        dprint(2, "\tTVCT found. total %d channels\n", ctx->vct->numChannels);
425                else {
426                        dprint(0, "!! cvct->vct err %d\n", status);
427                        ctx->vct = NULL;
428                }
429        }
430       
431        if (tvct)
432                FreeAtscTable(tvct);
433        if (cvct)
434                FreeAtscTable(cvct);
435
436        if (gDmcTestSkipVctDownload) // cafrii 060628 add
437                Dmc_FreeAtscTable(&ctx->vct);
438               
439        return status;
440       
441}
442
443
444
445//  doDmc_TuneByVctChannel
446// 
447//  ¼±ÅÃµÈ VCT subchannel Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© µðÁöÅÐ Æ©´×À» ¼öÇàÇÑ´Ù.
448//  Æ©´×Çϱâ Àü¿¡ Ç×»ó ÀÏÄ¡ÇÏ´Â PSI Á¤º¸°¡ ÀÖ´ÂÁö¸¦ È®ÀÎÇÑ´Ù.
449//
450//    statusOK
451//    statusInvalidPSI, statusInvalidVCT, statusNoPSI
452//    statusVideoError
453//    statusCancelled
454//
455STATUS doDmc_RfTuneByVctSubChannel(ChannelTuneContext *ctx, xvctChannelPtr_t channel)
456{
457        STATUS status;
458        TuneParam *tuneParam = &ctx->param;
459        DMC_VIDEO_CACHE cache;
460        PidInfo pidinfo;
461
462        if (channel == NULL) return statusInvalidArgument;
463
464        dprint(2, "\ttune vct subchannel #%d\n", channel->program_number);
465#if USE_PERF_MON
466        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 0);
467#endif
468       
469        status = doDmc_GetPmtByProgramNumber(ctx, channel->program_number);
470       
471        if (status == statusCancelled)  // PMT ¹Þ´Â ÀÛ¾÷Àº blocking ÀÛ¾÷À̹ǷΠcancel üũ ÇÊ¿ä.
472                return statusCancelled;
473
474        if (status != statusOK || ctx->pat == NULL || ctx->pmt == NULL)
475        {
476                if (tuneParam->flag & CTF_DontUseVctRecover)
477                        return statusInvalidVCT;
478                       
479                // cafrii 060707 add
480                // vctÀÇ program number°¡ À߸øµÈ °æ¿ì°¡ ÀÖ´Ù.
481                // vct¸¦ ºñ·ÔÇÑ PSIP¿¡´Â ¿©·¯ ¸¹Àº Á¤º¸°¡ ÀÖÀ¸¹Ç·Î,
482                // À̸¦ ±×³É ¹ö¸®±â´Â ¾Æ±õ´Ù.
483                // ±×·¡¼­ smart ÇÏ°Ô program number¸¦ º¹±¸ÇÏ´Â ÀÛ¾÷À» ¼öÇàÇÑ´Ù.
484
485                status = doDmc_RecoverVctProgramNumber(ctx, channel);
486
487                // ¼öÇà °á°ú¿¡ µû¶ó channel->program_number°¡ º¯°æ µÉ ¼öµµ ÀÖ´Ù.
488
489                if (status == statusCancelled)  // PMT ¹Þ´Â ÀÛ¾÷Àº blocking ÀÛ¾÷À̹ǷΠcancel üũ ÇÊ¿ä.
490                        return statusCancelled;
491        }
492
493        // cafrii 070718 change
494        // ³ªÁß¿¡ pid°¡ ¿ÏÀüÈ÷ °áÁ¤ µÈ ÈÄ¿¡ updateÇϵµ·Ï ÇÏÀÚ.
495        //ctx->pcrPid = ctx->vidPid = ctx->audPid = 0;
496       
497        status = Dmc_DecidePidInfo2(ctx->pmt, channel->descriptors, 
498                                        channel->descriptor_length, &pidinfo, 0);
499       
500        if (status == statusOK && pidinfo.bValid) {
501                dprint(2, "\t pid decided. pva %x %x %x, type va %d %d\n", 
502                        pidinfo.pcr, pidinfo.video, pidinfo.audio,
503                        pidinfo.videoType, pidinfo.audioType);
504        }
505        else {
506                pidinfo.pcr = pidinfo.video = pidinfo.audio = 0;
507        }
508
509#if USE_PERF_MON
510        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 1);
511#endif
512
513        doDmc_SelectAudioStream(ctx->pmt, channel, &(pidinfo.audio), &(pidinfo.audioType));
514        doDmc_SelectVideoStream(ctx->pmt, channel, &(pidinfo.video), &(pidinfo.videoType));
515
516        if (pidinfo.pcr == 0 || 
517                (pidinfo.video == 0 && pidinfo.audio == 0)) {
518                dprint(1, "!! No valid video or audio pid..\n");
519                return statusInvalidVCT;
520        }
521
522        // cafrii 070718 add check.
523        // ÀÌ Àü¿¡ ÀÌ¹Ì ½ÇÆÐÇÑ pid¶ó¸é ´Ù½Ã ½ÃµµÇÒ Çʿ䰡 ¾øÀ½.
524        if (ctx->pid_tune_fail_count > 0 &&
525                DHL_OS_GetMsCount() - ctx->pid_tune_fail_time < 1000*20 &&
526                ctx->pcrPid == pidinfo.pcr &&
527                ctx->vidPid == pidinfo.video &&
528                ctx->audPid == pidinfo.audio &&
529                ctx->vidType == pidinfo.videoType &&
530                ctx->audType == pidinfo.audioType)
531        {
532                dprint(0, "!! pid pvat (%x %x %x %x) already failed at %u ms before..\n",
533                        ctx->pcrPid, ctx->vidPid, ctx->audPid, ctx->audType,
534                        (DHL_OS_GetMsCount() - ctx->pid_tune_fail_time)*1000/1000);
535                return statusInvalidVCT;
536        }       
537
538        ctx->pcrPid = pidinfo.pcr;
539        ctx->vidPid = pidinfo.video;
540        ctx->audPid = pidinfo.audio;
541        ctx->audType = pidinfo.audioType;
542        ctx->vidType  = pidinfo.videoType;
543
544        // ¸ðµç pid Á¤º¸°¡ Áغñ µÇ¾úÀ½.
545        // ƯÁ¤ descramble systemÀÇ °æ¿ì pmt pid Á¤º¸¸¦ ÇÊ¿ä·Î Çϱ⵵ ÇϹǷÎ
546        // callbackÀ» ÅëÇØ¼­ pid Á¤º¸¸¦ notifyÇØÁØ´Ù.
547
548        if (ctx->pmt) { // cafrii 070711 bugfix! check pmt null
549                // cafrii 070201 add
550                doDmc_NotifyPidInfo(ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->pmt->PID);
551        }
552       
553        dprint(2, "\tdecoding p%x, v%x(t%d), a%x(t%d) start..\n", 
554                         ctx->pcrPid, ctx->vidPid, ctx->vidType, ctx->audPid, ctx->audType);
555
556
557// arzhna, 100203
558// VCT¿¡ ÀÇÇÑ Tuneµµ CA PMT¸¦ Àü´ÞÇϵµ·Ï ¼öÁ¤
559// APP¿¡¼­ CableCardÀåÂø½Ã Æ©´× ¸ðµå¿¡ ´ëÇØ Ãë»ç ¼±ÅÃÇϵµ·Ï ÇÑ´Ù
560//
561// doDmc_Notify()·Î app¿¡ notify,
562// app¿¡¼­ ó¸®ÇÏ¿© CARD¿¡ reportÇÑ´Ù.
563        {
564                PSIChangeNotifyInfo pcni;
565                memset(&pcni, 0, sizeof(pcni));
566       
567                pcni.pmtchanged = TRUE;         // This is PMT
568                pcni.pmt = ctx->pmt;          // new PMT       
569
570                // CableCard ¸ðµå¿¡¼­´Â PSI·Î¸¸ Æ©´×À» Çϴµ¥,
571                // Æ©´×À» Çϱâ Àü¿¡ PMT report¸¦ ¼öÇàÇÑ´Ù.
572                dprint(2, "\tReport CaPmt (pid %d,%d)\n", ctx->vidPid, ctx->audPid);
573
574                // arzhna, 100203
575                // CA PMT¸¦ Àü´ÞÇϱâ À§ÇÑ callback È£Ãâ
576                // DMC_NOTIFY_CaPmt event¸¦ º°µµ·Î ¸¸µé¾î ó¸®
577                doDmc_Notify(DMC_NOTIFY_CaPmt, (UINT32)&pcni); 
578        }
579
580
581#if USE_PERF_MON
582        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0);
583#endif
584
585#if SUPPORT_DMW_VIDEO_CACHE
586        // Ȥ½Ã cache Á¤º¸°¡ ÀÖ´ÂÁö load ÇØº»´Ù.
587        cache = DHL_AV_LoadVideoFromCache(ctx->rf, ctx->program_number, 
588                                        ctx->vidPid, ctx->pcrPid);
589#else
590        cache = (DMC_VIDEO_CACHE)NULL;
591#endif
592
593        status = doDmc_StartDigital(ctx->vidPid, ctx->audPid, ctx->pcrPid, cache, ctx->vidType, ctx->audType);
594
595        // Video Context¸¦ ¸¸µå´Â ÀÛ¾÷ ¿ª½Ã blocking ÀÛ¾÷À̹ǷΠcancel üũ..
596        if (status == statusCancelled) {
597                doDmc_ClearProgramInfo();
598                return statusCancelled;
599        }
600               
601        if (status) {
602                dprint(1, "!! cannot start with CVCT pids, status %d\n", status);
603                doDmc_ClearProgramInfo();
604                return status; // statusScrambled, statusVideoError, ...
605        }
606
607#if USE_PERF_MON
608        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1);
609#endif
610
611        doDmc_UpdateProgramInfoDigital(tuneParam->rf, tuneParam->type, TUNE_METHOD_ByVCT,
612                        Dmc_GetMajorNumber(ctx->vct->is_cvct, channel), //tuneParam->major
613                        Dmc_GetMinorNumber(ctx->vct->is_cvct, channel), //tuneParam->minor
614                        channel->program_number,
615                        ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->vidType, ctx->audType);
616                // retry flag°¡ »ç¿ëµÇ¾ú´Ù¸é ½ÇÁ¦ user°¡ ÁöÁ¤ÇÑ major/minor ¿Í ´Ù¸¦ ¼ö ÀÖ´Ù. ÁÖÀÇ..
617                // cafrii 060725, tune paramÀÇ major/minor °ª º¸´Ù, vctÀÇ Á¤º¸¸¦ º¸¿©ÁÖÀÚ.
618
619        doDmc_UpdatePsiInfo(ctx->pat, ctx->pmt);
620        ctx->pat = NULL;
621        ctx->pmt = NULL;
622       
623        return statusOK;
624
625}
626
627
628
629// doDmc_RfTuneByVct
630//
631//  ´Ù¿î·Îµå ¹ÞÀº VCT¸¦ ÀÌ¿ëÇÏ¿© Æ©´×À» ÇÑ´Ù. (tuneParam->vctPtr)
632//  TuneParam¿¡ ÀÖ´Â »ç¿ëÀÚÀÇ ¿ä±¸»çÇ×´ë·Î Æ©´×À» ÇÑ´Ù (major/minor)
633// 
634//
635// °¡´ÉÇÑ ¸®Åϰªµé:
636//  statusOK              : AV decoding success
637//  statusCancelled       : user¿¡ ÀÇÇØ Ãë¼Ò µÇ¾úÀ½
638//  statusNoVCT/InvalidVCT/NoPSI
639//  statusInvalidVCT      : VCTÀÇ ³»¿ëÀÌ ¿Ã¹Ù¸£Áö ¸øÇÏ¿© ÁøÇà ¾ÈµÊ
640//  statusChannelNotFound : »ç¿ëÀÚ°¡ ÁöÁ¤ÇÑ Ã¤³ÎÀ» ãÁö ¸øÇßÀ½.
641//  statusVideoError      : ¸ðµç Á¤º¸¸¦ Á¦´ë·Î ¼ö½ÅÇÏ¿´À¸³ª AV decoding½Ã¿¡ ¿¡·¯ ¹ß»ý
642
643STATUS doDmc_RfTuneByVct(ChannelTuneContext *ctx)
644{
645        int i;
646        STATUS status;
647        STATUS returnStatus = statusOK;  // ÃÖÁ¾ÀûÀ¸·Î ÀÌ ÇÔ¼ö¸¦ return ÇÒ ¶§ »ç¿ëÇÒ status°ª..
648        UINT16 major, minor;
649       
650        xvctChannelPtr_t channel;
651        UINT32 currentMajorMinor;
652        BOOL bChannelFound;
653       
654        TuneParam *tuneParam = &ctx->param;
655
656        dprint(1, "doDmc_RfTuneByVct: %d-%d\n", tuneParam->major, tuneParam->minor);
657       
658        if (ctx->vct == NULL)
659                return statusInvalidState;
660               
661        if (tuneParam->major == 0)
662        {
663                //-------------------
664                // unspecified tuning
665                // caller°¡ Á÷Á¢ Major/minor¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀº °æ¿ìÀÌ´Ù.
666                // tuneParam->major, tuneParam->minor ¸ðµÎ 0 ÀÌ´Ù.
667                // À̶§´Â ÀÚµ¿ÀûÀ¸·Î retry loopÀ¸·Î µé¾î°£´Ù.
668                // ±×·¯³ª °è¼ÓÀûÀ¸·Î retry¸¦ ÇÒ °ÍÀÎÁö ¾Æ´ÑÁö´Â Retry flag¿¡ µû¶ó¼­ °áÁ¤µÈ´Ù.
669                //
670                currentMajorMinor = 0;
671                dprint(2, "\tunspecified tuning: search from 0-0\n");
672               
673                goto label_retry_vct;
674               
675        } // end unspecified tuning
676
677        //-------------------
678        // Specified Tuning :
679        // Á÷Á¢ Major/minor ¹øÈ£¸¦ ÁöÁ¤Çؼ­ ±× ä³ÎÀ» Æ©´×ÇÏ´Â ¹æ¹ý
680        // CTF_RetryMainChannelÀÌ setµÇ¸é Mainä³ÎÀº ´Ù½Ã Æ©´× ½Ãµµ ÇÑ´Ù. (1ȸÇÑ)
681        //
682        // find 'the channel' major-minor. Á¤È®ÇÏ°Ô ÀÏÄ¡ÇÏ´Â M-m ä³ÎÀ» ã¾Æ¾ß¸¸ ÇÑ´Ù.
683        //
684        bChannelFound = FALSE;
685
686        // caller´Â Á÷Á¢ÀûÀ¸·Î OnePartNumber·Î È£ÃâÇßÀ» ¼öµµ ÀÖ°í, (minor°¡ ƯÁ¤ indication°ª)
687        // Raw major/minor·Î È£ÃâÇßÀ» ¼öµµ ÀÖ´Ù. (major »óÀ§ 6ºñÆ®°¡ 1)
688        //
689        if (tuneParam->minor == ONE_PART_CHANNEL_INDICATOR) {
690                dprint(2, "\t  tune with OnePartChannel %d\n", tuneParam->major);
691        }
692        else if (IsOnePartChannelNumber(tuneParam->major)) 
693        {
694                // À̰ÍÀº Raw major/minor·Î È£ÃâµÈ OnePartNumberÀÌ´Ù. º¯È¯ÀÌ ÇÊ¿äÇÏ´Ù.
695                UINT16 nOnePartChannelNumber;
696                nOnePartChannelNumber = ConvertToOnePartChannelNumber(tuneParam->major, tuneParam->minor);
697               
698                dprint(2, "\t  change %d-%d to OnePartChannelNumber %d\n", 
699                                tuneParam->major, tuneParam->minor, nOnePartChannelNumber);
700                tuneParam->major = nOnePartChannelNumber;
701                tuneParam->minor = ONE_PART_CHANNEL_INDICATOR;
702        }
703
704        //----------------------------
705        //  ÀÌÁ¦ ä³ÎÀ» ã¾Æº»´Ù.
706        //
707        dprint(2, "\tspecified tuning: try tune %d-%d..\n", tuneParam->major, tuneParam->minor);
708       
709        for (i=0; i<ctx->vct->numChannels; i++)
710        {
711                channel = &(ctx->vct->channel[i]);
712               
713                major = Dmc_GetMajorNumber(ctx->vct->is_cvct, channel);
714                minor = Dmc_GetMinorNumber(ctx->vct->is_cvct, channel);
715               
716                if (major == tuneParam->major && minor == tuneParam->minor) 
717                {
718                        if (!channel->hidden || (tuneParam->flag & CTF_ShowHiddenChannelAlso)) {
719                                // hiddenµµ ¾Æ´Ï°í, hiddenÀÌ´õ¶óµµ ShowHidden flag°¡ ÀÖÀ¸¸é ó¸® °¡´ÉÇÔ..
720                                bChannelFound = TRUE;
721                                break;
722                        }
723                        else {
724                                dprint(2, "!! channel found, but hidden! ignore it!\n");
725                                bChannelFound = FALSE;
726                        }
727                }
728        }
729
730        if (bChannelFound)
731        {
732                dprint(2, "\tchannel %d-%d found. (specified channel)\n", major, minor);
733
734                status = doDmc_RfTuneByVctSubChannel(ctx, channel);
735
736                if (status == statusCancelled)
737                        return statusCancelled;
738               
739                if (status == statusOK) {
740                        return statusOK;
741                }
742                returnStatus = status;
743        }
744        else 
745        {
746                dprint(1, "!! %d-%d not found in CVCT\n", tuneParam->major, tuneParam->minor);
747                returnStatus = statusChannelNotFound;
748        }
749       
750        // specified tuning ¹æ¹ýÀ» »ç¿ëÇßÀ»¶§ tuning¿¡ ½ÇÆÐÇϸé
751        // ÇöÀç ¿É¼Ç¿¡ µû¶ó¼­ retry¸¦ ÇÒ °ÍÀÎÁö ¾Æ´ÑÁö¸¦ °áÁ¤ÇÑ´Ù.
752        //
753
754        if ((tuneParam->flag & CTF_RetryOtherChannel)) {
755                dprint(2, "\t retry other channel.. search from %d-%d\n", 
756                                                        tuneParam->major, tuneParam->minor);
757                currentMajorMinor = (tuneParam->major << 16UL) + (tuneParam->minor);
758                        // ÇöÀç ä³Î MM: retry¸¦ ÇÒ¶§ °Ë»öÀÇ ½ÃÀÛÁ¡ÀÌ µÈ´Ù.
759        }
760        else {
761                // Àç½Ãµµ¸¦ ÇÏÁö ¾Ê´Â´Ù. ¿¡·¯¸¦ ¸®ÅÏÇÔ.
762                //  returnStatus´Â ÃÖÁ¾ ¿¡·¯ °ªÀ» º¸À¯Çϰí ÀÖ´Ù.
763                //  returnStatus : ChannelNotFound, VideoError, InvalidVCT µî.
764                //
765                return returnStatus;
766        }
767
768label_retry_vct:
769
770        //---------------------         
771        // VCT retry mode
772        //
773        // Retry¸ðµåÀÏ °æ¿ì ¿¡·¯°¡ ¹ß»ýÇÏ¸é °è¼Ó ¹Ýº¹ÇÑ´Ù.
774        // ´õÀÌ»ó ä³Î Á¤º¸°¡ ¾øÀ» ¶§ ±îÁö ¹Ýº¹.
775 
776        while (1)
777        {
778                // currentMM º¸´Ù "Å«" MM Áß¿¡¼­ ÃÖ¼Ò MMÀ» ã´Â´Ù.
779                // ´Ü CTF_SkipNonFamilyChannel ¸ðµå¿¡¼­´Â Major°¡ °°Àº ä³Î·Î Á¦ÇÑÇÔ.
780                //
781                channel = doDmc_FindNextVctChannel(ctx->vct, currentMajorMinor, 
782                                                (tuneParam->flag & CTF_SkipNonFamilyChannel) ? TRUE : FALSE, 
783                                                (tuneParam->flag & CTF_ShowHiddenChannelAlso) ? FALSE : TRUE);
784               
785                if (channel == NULL) { // ´õÀÌ»ó ¿øÇϴ ä³Î ¾øÀ½.
786                        dprint(1, "\tNo more valid channel in VCT\n");
787                        return statusChannelNotFound;
788                }
789                               
790                // ä³ÎÀÌ ¹ß°ßµÇ¾úÀ½. 'channel' pointer°¡ °¡¸®Å°´Â °÷¿¡ ¿øÇÏ´Â Á¤º¸°¡ ÀÖ´Ù.
791
792                major = Dmc_GetMajorNumber(ctx->vct->is_cvct, channel);
793                minor = Dmc_GetMinorNumber(ctx->vct->is_cvct, channel);
794               
795                currentMajorMinor = (major << 16UL) + minor;
796                dprint(2, "\t  found channel  %d-%d (unspecified or retry channel)\n", major, minor);
797               
798                status = doDmc_RfTuneByVctSubChannel(ctx, channel);
799               
800                if (status == statusCancelled)
801                        return statusCancelled;
802               
803                if (status == statusOK) {
804                        return statusOK;
805                }
806                returnStatus = status;
807               
808                // ä³Î °Ë»ö¿¡ ½ÇÆÐ. ´ÙÀ½ ä³Î·Î Àç½Ãµµ Çϱâ Àü¿¡ retry ¸ðµåÀÎÁö ¾Æ´ÑÁö üũ¸¦ ÇÑ´Ù.
809                if ((tuneParam->flag & CTF_RetryOtherChannel)) {
810                        dprint(2, "!! cannot start %d-%d in CVCT! try next channel..\n", major, minor);
811                        continue;
812                }
813                else {
814                        // retry ¸ðµå°¡ ¾Æ´Ï¹Ç·Î ±×³É ½ÇÆÐ·Î Á¾·á. returnStatus´Â ¸¶Áö¸· ¿¡·¯ °ªÀ» °¡Áö°í ÀÖ´Ù.
815                        dprint(2, "!! failed in starting %d-%d in CVCT! No retry, last err %d\n", 
816                                                major, minor, returnStatus);
817                        // returnStatus: InvalidVCT or VideoError µî..
818                        return returnStatus;
819                }
820        }
821
822}
823
824
825
826
827STATUS doDmc_RfTuneByPsiSubChannel(ChannelTuneContext *ctx, int PmtPID, int program_number)
828{
829        STATUS status;
830        TuneParam *tuneParam = &ctx->param;
831        DMC_VIDEO_CACHE cache;
832        PidInfo psiPid;
833
834        if (ctx->pmt) {
835                dprint(2, "\tfree previous pmt\n");
836                FreePMT(ctx->pmt);
837                ctx->pmt = NULL;
838        }
839
840#if USE_PERF_MON
841        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 0);
842#endif
843       
844        status = Dmc_GetPMT(Dmc_GetCurrentTsd(), PmtPID, program_number, 
845                                        &ctx->pmt, 
846                                        g_Timeout_PmtLoading*1000/1000, 
847                                        Dmc_CheckCancel);
848
849        if (status == statusCancelled) 
850                return statusCancelled;
851
852        else if (status) {
853                dprint(1, "!! PMT load failed.\n");
854                return statusNoPSI;
855        }
856
857#if USE_PERF_MON
858        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, 1);
859#endif
860
861        // cafrii 070718 change
862        // ³ªÁß¿¡ pid°¡ ¿ÏÀüÈ÷ °áÁ¤ µÈ ÈÄ¿¡ updateÇÔ.
863        //ctx->pcrPid = ctx->vidPid = ctx->audPid = 0;
864
865        status = Dmc_DecidePidInfo(ctx->pmt, NULL, &psiPid, 0);
866
867        if (status == statusOK && psiPid.bValid) 
868        {
869                dprint(2, "\t pid from pmt decided. pva %x %x %x, type va %d %d\n", 
870                        psiPid.pcr, psiPid.video, psiPid.audio,
871                        psiPid.videoType, psiPid.audioType);
872        }
873        else {
874                // ¿¡·¯ üũ´Â ¾Æ·¡¿¡¼­ audio pid ±îÁö °áÁ¤ µÈ ´ÙÀ½¿¡ ÇÏÀÚ.
875                psiPid.pcr = psiPid.video = psiPid.audio = 0;
876        }
877
878        doDmc_SelectAudioStream(ctx->pmt, NULL, &(psiPid.audio), &(psiPid.audioType));
879        doDmc_SelectVideoStream(ctx->pmt, NULL, &(psiPid.video), &(psiPid.videoType));
880
881        if (psiPid.pcr == 0 || 
882                (psiPid.video == 0 && psiPid.audio == 0)) 
883        {
884                dprint(1, "!! No valid video or audio pid..\n");
885                return statusInvalidPSI;
886        }
887
888        // cafrii 070718 add check.
889        // ÀÌ Àü¿¡ ÀÌ¹Ì ½ÇÆÐÇÑ pid¶ó¸é ´Ù½Ã ½ÃµµÇÒ Çʿ䰡 ¾øÀ½.
890        if (ctx->pid_tune_fail_count > 0 &&
891                DHL_OS_GetMsCount() - ctx->pid_tune_fail_time < 1000*20 &&
892                ctx->pcrPid == psiPid.pcr &&
893                ctx->vidPid == psiPid.video &&
894                ctx->audPid == psiPid.audio &&
895                (ctx->audType == 0 || ctx->audType == psiPid.audioType))
896        {
897                dprint(0, "!! pid pvax (%x %x %x %x) already failed at %u ms before..\n",
898                        ctx->pcrPid, ctx->vidPid, ctx->audPid, ctx->audType,
899                        (DHL_OS_GetMsCount() - ctx->pid_tune_fail_time)*1000/1000);
900                return statusInvalidPSI;
901        }       
902
903        // ¸ðµç pid Á¤º¸ Áغñ ¿Ï·á.
904        ctx->pcrPid = psiPid.pcr;
905        ctx->vidPid = psiPid.video;
906        ctx->audPid = psiPid.audio;
907        ctx->audType = psiPid.audioType;
908        ctx->vidType = psiPid.videoType;
909
910
911        // cafrii 070412, add check pmt null
912        if (ctx->pmt) { 
913                // cafrii 070201 add
914                doDmc_NotifyPidInfo(ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->pmt->PID);
915        }
916
917        dprint(2, "\t vPid %x (t%d), aPid %x (t%d), pPid %x decoding start..\n",
918                        ctx->vidPid, ctx->vidType, ctx->audPid, ctx->audType, ctx->pcrPid);
919
920// arzhna, 100129
921// doDmc_Notify()·Î app¿¡ notify,
922// app¿¡¼­ ó¸®ÇÏ¿© CARD¿¡ reportÇÑ´Ù.
923// ±âÁ¸ÀÇ ·çƾÀº »èÁ¦
924        {
925                PSIChangeNotifyInfo pcni;
926                memset(&pcni, 0, sizeof(pcni));
927       
928                pcni.pmtchanged = TRUE;         // This is PMT
929                pcni.pmt = ctx->pmt;          // new PMT
930
931                // CableCard ¸ðµå¿¡¼­´Â PSI·Î¸¸ Æ©´×À» Çϴµ¥,
932                // Æ©´×À» Çϱâ Àü¿¡ PMT report¸¦ ¼öÇàÇÑ´Ù.
933                dprint(2, "\tReport CaPmt (prog# %d, pid %d,%d)\n", 
934                                        program_number, ctx->vidPid, ctx->audPid);
935               
936                // arzhna, 100203
937                // CA PMT¸¦ Àü´ÞÇϱâ À§ÇÑ callback È£Ãâ
938                // DMC_NOTIFY_CaPmt event¸¦ º°µµ·Î ¸¸µé¾î ó¸®
939                doDmc_Notify(DMC_NOTIFY_CaPmt, (UINT32)&pcni); 
940                }
941               
942#if USE_PERF_MON
943        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0);
944#endif
945
946#if SUPPORT_DMW_VIDEO_CACHE
947        // Ȥ½Ã cache Á¤º¸°¡ ÀÖ´ÂÁö load ÇØº»´Ù.
948        cache = (DMC_VIDEO_CACHE)DHL_AV_LoadVideoFromCache(ctx->rf, ctx->program_number, 
949                                                ctx->vidPid, ctx->pcrPid);
950#else
951        cache = (DMC_VIDEO_CACHE)NULL;
952#endif
953
954        status = doDmc_StartDigital(ctx->vidPid, ctx->audPid, ctx->pcrPid, cache, ctx->vidType, ctx->audType);
955
956        if (status == statusCancelled) {
957                doDmc_ClearProgramInfo();
958                return statusCancelled;
959        }
960       
961        if (status) {
962                doDmc_ClearProgramInfo();
963                return status;
964        }
965
966#if USE_PERF_MON
967        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1);
968#endif
969
970        doDmc_UpdateProgramInfoDigital(tuneParam->rf, tuneParam->type, TUNE_METHOD_ByPSI,
971                                                0, 0, program_number,
972                                                ctx->vidPid, ctx->audPid, ctx->pcrPid, ctx->vidType, ctx->audType);
973
974        doDmc_UpdatePsiInfo(ctx->pat, ctx->pmt);
975        ctx->pat = NULL;
976        ctx->pmt = NULL;
977
978        return statusOK;       
979}
980
981
982
983/***********
984        CmdRfTune ÇÔ¼ö¿¡¼­ Ç®¸®´Â Sub-fuctionÀÌ´Ù.
985       
986        NIMÀÇ frequency & demod ¼³Á¤Àº ¿Ï·áµÈ »óÅÂ..
987        PSI µ¥ÀÌÅÍ (PAT/PMTs)¸¦ ´Ù¿î·Îµå ¹Þ¾Æ ÂüÁ¶ÇÏ¿© tuneParam¿¡¼­ ÁöÁ¤ÇÑ ´ë·Î Æ©´×À» ½ÃµµÇÑ´Ù.
988        ÇÁ·Î±×·¥À» ¼±ÅÃÇϴµ¥ tuneParam->progNumber¸¦ »ç¿ëÇÑ´Ù.
989       
990***********/
991STATUS doDmc_RfTuneByPsi(ChannelTuneContext *ctx)
992{
993        int i;
994        STATUS status;
995        STATUS returnStatus;
996
997        int _second = 1000;
998        int idx;  // PAT index
999        TuneParam *tuneParam = &ctx->param;
1000       
1001        if (Dmc_CheckCancel()) goto label_cancelled;
1002
1003        dprint(1, "RfTuneByPsi: prognum %d\n", tuneParam->progNumber);
1004
1005        // pat°¡ ¼ö½ÅÀÌ ¾ÈµÇ¾î ÀÖ´Â °æ¿ì¶ó¸é ´Ù½Ã ¼ö½ÅÇÑ´Ù.
1006        //
1007        if (ctx->pat == NULL) {
1008                dprint(2, "\tGet New PAT..\n");
1009                status = Dmc_GetPAT(Dmc_GetCurrentTsd(), &ctx->pat, 
1010                                                        g_Timeout_PatLoading*_second/1000, 
1011                                                        Dmc_CheckCancel);
1012
1013                if (status == statusCancelled) goto label_cancelled;
1014       
1015                else if (status) {
1016                        dprint(1, "!! PAT load failed, %d\n", status);
1017                        returnStatus = statusNoPSI;
1018                        goto label_end_tune;
1019                }
1020                if (Dmc_CheckCancel()) goto label_cancelled;
1021        }
1022
1023        dprint(2, "\tPAT found. total %d programs\n", ctx->pat->numPrograms);
1024
1025        if (ctx->pat->numPrograms == 0 || ctx->pat->programs == NULL) {
1026                dprint(2, "!! invalid PSI.. no program!\n");
1027                returnStatus = statusInvalidPSI;
1028                goto label_end_tune;
1029        }               
1030
1031        if (tuneParam->progNumber == 0) {
1032                // Unspecified tuning.
1033                // caller°¡ ƯÁ¤ ÇÁ·Î±×·¥ ¹øÈ£¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀº °æ¿ìÀÌ´Ù.
1034                // ÀÌ °æ¿ì ´ëÇ¥ ÇÁ·Î±×·¥ (Main program)À» ¼±ÅÃÇØ¾ß Çϴµ¥,
1035                // ÇöÀç´Â ±×³É ¸Ç óÀ½ °ÍÀ» »ç¿ëÇÑ´Ù.
1036               
1037                idx = 0; // ¸Ç óÀ½ ÇÁ·Î±×·¥ ºÎÅÍ °Ë»ö ½ÃÀÛÇÑ´Ù.
1038                tuneParam->progNumber = ctx->pat->programs[0].program_number; 
1039                // ÀÌ·¸°Ô Çϸé Ç×»ó ¹Ýµå½Ã ã¾ÆÁö°Ô µÈ´Ù.
1040                dprint(2, "\t unspecified tuning. start from index 0\n");
1041        }
1042        else {
1043                // find 'the program' whose program number is 'progNumber'.
1044                // if not found, we report error directly.
1045                //
1046                idx = -1;
1047                for (i=0; i<ctx->pat->numPrograms; ++i) {
1048                        if (ctx->pat->programs[i].program_number == tuneParam->progNumber) {
1049                                idx = i;
1050                                break;
1051                        }
1052                }
1053        }
1054       
1055        if (idx < 0 || idx >= ctx->pat->numPrograms) { // cafrii 060628 bugfix!! i->idx
1056                dprint(1, "!! program number %d not found!\n", tuneParam->progNumber);
1057                returnStatus = statusChannelNotFound;
1058                goto label_end_tune;
1059        }
1060       
1061        //------ Program decoding loop -------------
1062        // 'idx' is index of program table (PAT)
1063        // Retry flag°¡ ÀÖ´Â °æ¿ì¶ó¸é ¼º°ø ÇÒ ¶§±îÁö °è¼Ó retry¸¦ ÇÏ°Ô µÈ´Ù.
1064        // idxºÎÅÍ ½ÃÀÛÇØ¼­ ¸ðµç programÀ» ¸ðµÎ °Ë»çÇØº»´Ù. (wrap-around)
1065        //
1066        // cafrii 060727 bugfix
1067        //   ¹«ÇÑ ·çÇÁ µµ´Â ¹®Á¦ ¼öÁ¤. cancelÀº µÇ´Ï±î Ä¡¸íÀûÀÌÁø ¾ÊÀ½.
1068        //   i´Â Ƚ¼ö counting¸¸ Çϰí, idx·Î indexing.
1069        //
1070        //for (i=idx; i<ctx->pat->numPrograms; i=(i+1)%ctx->pat->numPrograms)
1071        for (i=0; i<ctx->pat->numPrograms; i++, idx=(idx+1)%ctx->pat->numPrograms) 
1072        {
1073                dprint(2, "\ttry program [%d], pid %d, program number #%d\n", 
1074                                                idx, 
1075                                                ctx->pat->programs[idx].program_map_PID,
1076                                                ctx->pat->programs[idx].program_number);
1077
1078                // MPEG_PAT
1079                status = doDmc_RfTuneByPsiSubChannel(ctx, 
1080                                        ctx->pat->programs[idx].program_map_PID, 
1081                                        ctx->pat->programs[idx].program_number);
1082               
1083                if (status == statusCancelled) goto label_cancelled;
1084
1085                if (status == statusOK) {
1086                        returnStatus = statusOK;
1087                        goto label_end_tune;
1088                }
1089
1090                // ±×¹ÛÀÇ ¸ðµç ¿¡·¯..
1091                // flag¿¡ µû¶ó¼­ retryÀÇ ¿©ºÎ°¡ °áÁ¤µÈ´Ù.
1092               
1093                if (tuneParam->flag & CTF_RetryOtherProgram) {
1094                        // ´ÙÀ½ program Àç½Ãµµ
1095                        dprint(2, "\t! Psi tune err %d;.. retry other program..\n", status);
1096                        continue;
1097                }
1098                else {
1099                        returnStatus = statusInvalidPSI;
1100                        goto label_end_tune;
1101                }
1102
1103        } //--------- end for loop -----------
1104
1105        dprint(1, "!! No valid program! stop!\n");
1106        returnStatus = statusInvalidPSI;
1107        goto label_end_tune;
1108
1109
1110label_cancelled:
1111        returnStatus = statusCancelled;
1112
1113label_end_tune:
1114        return returnStatus;
1115
1116}
1117
1118
1119
1120
1121
1122STATUS doDmc_RfTuneSetTuner(ChannelTuneContext *ctx)
1123{
1124        STATUS status = statusOK;
1125        UINT32 tickStartTunerSet;
1126        BOOL bLocked;   // signal lock status
1127        int strength;   // signal strength
1128        int _second = 1000;
1129
1130        DHL_RESULT dhr;
1131        UINT32 cap;
1132       
1133        TuneParam *tuneParam = &ctx->param;
1134
1135        // cafrii 060630 add, if already tuned to rf, skip!
1136        // modulation mode may be different..
1137        //
1138        if ((tuneParam->flag & CTF_ForceSetTuner) == 0 &&
1139                tuneParam->rf == DMW_HAL_GetCurrentRF() &&
1140                DMW_HAL_DetectNIMChannel())
1141        {
1142                //dprint(2, "\talready tuned to rf %d.. skip tune\n", ctx->rf);
1143                dprint(2, "\talready tuned to rf %d.. skip tuner setting\n", ctx->rf);
1144                // cafrii 070411 ¿ÀÇØ ¼ÒÁö°¡ ÀÖ´Â debug message ¹®±¸ ¼öÁ¤.
1145                return statusOK;
1146        }
1147
1148        dhr = DHL_FE_GetDeviceInfo(DEFAULT_TUNER_ID, eDHL_FE_DEV_CAPABILITY_1, &cap);
1149        if (dhr != DHL_OK) {
1150                dprint(0, "!! dev cap query err %d\n", dhr);
1151                DHL_ASSERT(FALSE, "");
1152        }
1153
1154        tickStartTunerSet = DHL_OS_GetMsCount();
1155
1156        // µðÁöÅÐ modulationÀÎ °æ¿ì
1157        //
1158        if (tuneParam->type != Modulation_NTSC)
1159        {
1160                int nModeToTry = 0;
1161                ModulationType aModes[5];
1162
1163                int i, type, lock_timeout;
1164
1165                int typeFirstTried; // cafrii 070227 add
1166
1167                type = tuneParam->type;
1168                if (type == Modulation_CableAuto) {
1169                        // Cable auto ¸ðµå´Â Analog ±îÁö Æ÷ÇÔÇÏ´Â °ÍÀÌÁö¸¸,
1170                        // ±¸ÇöÀÌ º¹ÀâÇϹǷΠ±×³É QamAuto ¸ðµå·Î °£ÁÖ.
1171                        type = Modulation_QAM;
1172                }
1173               
1174                if (tuneParam->flag & CTF_SkipQamModulation)
1175                {
1176                        dprint(2, "\t Skip QAM mode..\n");
1177                        if (cap & eDHL_TUCAP_VSB) {
1178                                aModes[nModeToTry++] = Modulation_8VSB;
1179                        }
1180                        else
1181                                dprint(0, "!! FE not support VSB, but SkipQam mode requested\n");
1182                }
1183                else if (type == Modulation_64QAM || type == Modulation_256QAM)
1184                {
1185                                // arzhna, 100407
1186                                // QAM Mode°¡ ÁöÁ¤µÇ¾úÀ»¶§ ÁöÁ¤µÇÁö ¾ÊÀº ´Ù¸¥ modeµµ tryÇÏÁö ¾Êµµ·Ï auto¿Í ³ª´«´Ù.
1187                        if ((cap & eDHL_TUCAP_QAMAUTO) && (tuneParam->flag & CTF_UseQamAutoMode)) {
1188                                aModes[nModeToTry++] = Modulation_QAM;
1189                        }
1190                        else if (cap & eDHL_TUCAP_QAM) {
1191                                // QAMAUTO´Â Áö¿øÇϸ鼭 QAMÀº Áö¿øÇÏÁö ¾Ê´Â FE°¡ ÀÖÀ¸¸é ¾ÈµÊ.
1192                                // Âü°í·Î Capability¿¡´Â QAM64¿Í QAM256¿¡ ±¸ºÐÀÌ ¾ø´Ù.
1193                                // µÎ QAM Áß¿¡ Çϳª¸¸ Áö¿øÇÏ´Â ±×·± demod´Â ¾øÀ» °Å¶ó°í °¡Á¤ÇÔ..
1194                                aModes[nModeToTry++] = (ModulationType)type;
1195                        }
1196                        else 
1197                                dprint(0, "!! FE not support QAM, but QAM requested. tucap 0x%x, req %d\n",     cap, type);
1198                }
1199                else if (type == Modulation_QAM)
1200                {
1201                        if ((cap & eDHL_TUCAP_QAMAUTO) && (tuneParam->flag & CTF_UseQamAutoMode)) {
1202                                aModes[nModeToTry++] = Modulation_QAM;
1203                        }
1204                        else if (cap & eDHL_TUCAP_QAM) {
1205                                // 64, 256 °¢°¢ ³ª´²¼­ µû·Î ½Ãµµ.. ¼ø¼­´Â ÀÏ´Ü callerÀÇ paramÀ» Á¸Áß..
1206                                // Qam auto ¸¦ request ÇÑ °æ¿ì¶ó¸é ¾îÂ¥ÇÇ qam auto°¡ Áö¿ø ¾ÈµÇ¹Ç·Î, ¾Æ¹«°Å³ª ¸ÕÀú..
1207                                if (type == Modulation_QAM) type = Modulation_256QAM;
1208                                aModes[nModeToTry++] = (ModulationType)type;
1209                                aModes[nModeToTry++] = (ModulationType)type == Modulation_64QAM ? Modulation_256QAM : Modulation_64QAM;
1210                        }
1211                        else 
1212                                dprint(0, "!! FE not support QAM, but QAM requested. tucap 0x%x, req %d\n",     cap, type);
1213                }
1214                else if (type == Modulation_8VSB) 
1215                {
1216                        if (cap & eDHL_TUCAP_VSB) {
1217                                aModes[nModeToTry++] = Modulation_8VSB;
1218                        }
1219                        else
1220                                dprint(0, "!! FE not support VSB but VSB requested\n");
1221
1222                        // Áö¿øÀÌ µÈ´Ù¸é Ãß°¡·Î QAM µµ ½Ãµµ..
1223                        if ((cap & eDHL_TUCAP_QAMAUTO) && (tuneParam->flag & CTF_UseQamAutoMode)) {
1224                                aModes[nModeToTry++] = Modulation_QAM;
1225                        }
1226                        else if (cap & eDHL_TUCAP_QAM) {
1227                                aModes[nModeToTry++] = Modulation_64QAM;
1228                                aModes[nModeToTry++] = Modulation_256QAM;
1229                        }
1230                }
1231
1232                if (nModeToTry == 0) {
1233                        dprint(0, "!! no mode to tune\n");
1234                        status = statusInvalidState;
1235                        goto label_tune_end;
1236                }
1237               
1238                typeFirstTried = type;
1239               
1240                for (i=0; i<nModeToTry; i++)  // ¼¼°¡Áö Modulation ¹æ½ÄÀ» Çϳª¾¿ try ÇÑ´Ù.
1241                {
1242                        type = aModes[i];
1243                        tickStartTunerSet = DHL_OS_GetMsCount();
1244                       
1245                        dprint(2, "\t%s changing rf %d, type %d (%s), offset %d, autoFreq %d..\n", 
1246                                i ? "!! retry" : "",
1247                                tuneParam->rf, type, ServiceTypeString(type), 
1248                                tuneParam->freqOffset, (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? 1 : 0);
1249
1250                        // cafrii 070710 use return value to check cancel
1251                        status = DMW_HAL_TunerSetChannel(tuneParam->rf, (ModulationType)type, 
1252                                                tuneParam->freqOffset, 
1253                                                (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? FREQTUNE_SHORT_SEARCH : FREQTUNE_FIXED,
1254                                                Dmc_CheckCancel);
1255
1256                        if (status == statusCancelled) 
1257                                goto label_cancelled;
1258
1259                        if (gDmcTestSkipCheckSignalLock) {
1260                                dprint(2, "\tskip signal detect..\n");
1261                                status = statusOK;
1262                                goto label_tune_end;
1263                        }
1264                        if (status)
1265                                goto label_tune_end;
1266                       
1267                        lock_timeout = g_Timeout_SignalLock; 
1268                       
1269                        while (1)  // wait until signal is locked.
1270                        {
1271                                bLocked = DMW_HAL_DetectNIMChannel();
1272                               
1273                                if (bLocked)  // ¸¸¾à lockÀÌ µÇ¾úÀ¸¸é ´õ ±â´Ù¸®Áö ¾Ê´Â´Ù. ¹Ù·Î break.
1274                                        break;
1275       
1276                                if ((DHL_OS_GetMsCount() - tickStartTunerSet) > (unsigned int)lock_timeout*_second/1000)
1277                                        break;  // time out!
1278       
1279                                if (Dmc_CheckCancel()) goto label_cancelled;
1280                               
1281                                DHL_OS_Delay(_second/20); // give chance for other task to take CPU control.
1282                        }
1283       
1284                        if (Dmc_CheckCancel()) goto label_cancelled;
1285       
1286                        if (bLocked && g_SignalThresholdForDigitalChannel) 
1287                        {
1288                                strength = DMW_HAL_GetSignalStrength();
1289                                if (strength < g_SignalThresholdForDigitalChannel) {
1290                                        dprint(1, "!! signal locked, but strength too weak! %d < threshold %d. stop!\n",
1291                                                                strength, g_SignalThresholdForDigitalChannel);
1292                                        bLocked = FALSE; // signal unlock°ú µ¿ÀÏÇÏ°Ô Ã³¸®ÇÑ´Ù.
1293                                }
1294                        }
1295       
1296                        if (bLocked) {
1297                                dprint(2, "\tsignal locked. %d ms\n", 
1298                                        (DHL_OS_GetMsCount()-tickStartTunerSet)*1000/1000);
1299                                goto label_tune_end;
1300                        }
1301
1302                        // retry¸¦ ÇÏÁö ¾Ê´Â Á¶°Ç.. NTSCÀÎ °æ¿ì, Air ¸ðµåÀÎ °æ¿ì..
1303                       
1304                        if (g_CurChannelType == ChannelType_Air)
1305                                break;
1306                       
1307                        // ÀÌ typeÀ¸·Î ½ÇÆÐÇßÀ¸¹Ç·Î ´Ù¸¥ typeÀ¸·Î ´Ù½Ã ½ÃµµÇÑ´Ù.
1308                        //
1309                } // end for modulation type
1310
1311                // signal is not locked!! do error proccessing..
1312       
1313                if (tuneParam->flag & CTF_RetryAnalogIfSignalUnlock) {
1314                        dprint(2, "\t signal unlock. retry Analog mode..\n");
1315                        tuneParam->type = Modulation_NTSC;  // force to NTSC..
1316                        if (tuneParam->rf) {
1317                                dprint(2, "\tchanging tuner rf %d, type %d..\n", tuneParam->rf, 0);
1318                                DMW_HAL_TunerSetChannel(tuneParam->rf, Modulation_NTSC, 0, 
1319                                                        FREQTUNE_SHORT_SEARCH,
1320                                                        Dmc_CheckCancel);
1321                                        // offset zero, auto adjust TRUE
1322                        }
1323                }
1324                else {
1325                        dprint(1, "!! digital signal unlocked. stop!\n");
1326
1327                        // cafrii 070227 add trick code
1328                        // ¾îÂ¥ÇÇ ½ÇÆÐÇÑ °ÍÀε¥, ¸Ç óÀ½ tryÇÑ demodulation ¹æ¹ýÀ¸·Î ¹Ù²ã ³õÀÚ.
1329                        // ´ÙÀ½ ¹ø¿¡ ÀÚµ¿ detect°¡ »¡¸® µÉ °ÍÀÓ.
1330
1331                        DMW_HAL_TunerSetChannel(tuneParam->rf, (ModulationType)typeFirstTried, 
1332                                                tuneParam->freqOffset, 
1333                                                (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? FREQTUNE_SHORT_SEARCH : FREQTUNE_FIXED,
1334                                                Dmc_CheckCancel);
1335                        // °á°ú´Â üũÇÒ ÇÊ¿ä ¾øÀ½..
1336                       
1337                        status = statusNoSignal;
1338                        goto label_tune_end;
1339                }
1340       
1341        }
1342        else // NTSC tuning
1343        {
1344                if (tuneParam->rf) {
1345                        dprint(2, "\tchanging tuner rf %d, type %d, offset %+d, autoFreq %d..\n",
1346                                        tuneParam->rf, tuneParam->type, tuneParam->freqOffset,
1347                                        (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? 1 : 0);
1348                        DMW_HAL_TunerSetChannel(tuneParam->rf, Modulation_NTSC, 
1349                                                tuneParam->freqOffset, 
1350                                                //FREQTUNE_SHORT_SEARCH,
1351                                                (tuneParam->flag & CTF_TunerAutoFreqAdjust) ? FREQTUNE_SHORT_SEARCH : FREQTUNE_FIXED,
1352                                                Dmc_CheckCancel);
1353                                // offset zero, auto adjust TRUE
1354                }
1355        }
1356
1357label_tune_end:
1358        return status;
1359
1360label_cancelled:
1361        return statusCancelled;
1362
1363}
1364
1365
1366
1367STATUS doDmc_RfTuneByPidOnly(ChannelTuneContext *ctx)
1368{
1369        STATUS status = statusOK;
1370        TuneParam *tuneParam = &ctx->param;
1371        DMC_VIDEO_CACHE cache;
1372       
1373        //----------------------------------------
1374        // tune by PIDs..       
1375
1376        // video pid, audio pid ¸ðµÎ 0À¸·Î ¼³Á¤Çؼ­ callÇϸé
1377        // pre-scan pid tuning ±â´ÉÀ» skipÇÏ´Â °ÍÀ¸·Î ¹Þ¾ÆµéÀδÙ.
1378        //
1379       
1380        if (tuneParam->pcrPid && 
1381                (tuneParam->vidPid || tuneParam->audPid) && 
1382                tuneParam->rf && 
1383                tuneParam->progNumber)  // prescan PID¿¡ ÀÇÇÑ Æ©´× ½Ãµµ.
1384        {
1385               
1386                dprint(2, "    Try using prescan pids pvat %x %x %x vt %x at %x rf %d #%d..\n",
1387                        tuneParam->pcrPid, tuneParam->vidPid, tuneParam->audPid, 
1388                        tuneParam->vidType, tuneParam->audType,
1389                        tuneParam->rf, tuneParam->progNumber);
1390
1391                ctx->vidPid = tuneParam->vidPid;
1392                ctx->audPid = tuneParam->audPid;
1393                ctx->pcrPid = tuneParam->pcrPid;
1394                ctx->audType = tuneParam->audType;
1395                ctx->vidType = tuneParam->vidType;
1396
1397#if USE_PERF_MON
1398        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0);
1399#endif
1400
1401#if SUPPORT_DMW_VIDEO_CACHE
1402                // Ȥ½Ã cache Á¤º¸°¡ ÀÖ´ÂÁö load ÇØº»´Ù.
1403                cache = (DMC_VIDEO_CACHE)DHL_AV_LoadVideoFromCache(ctx->rf, ctx->program_number, 
1404                                                ctx->vidPid, ctx->pcrPid);
1405#else
1406                cache = (DMC_VIDEO_CACHE)NULL;
1407#endif
1408
1409                status = doDmc_StartDigital(ctx->vidPid, ctx->audPid, ctx->pcrPid, cache, ctx->vidType, ctx->audType);
1410               
1411                if (status == statusCancelled) {
1412                        doDmc_ClearProgramInfo();
1413                        return statusCancelled;
1414                }
1415                else if (status) {
1416                        //if (err != timeoutError)
1417                                // timeout ¿ÜÀÇ ´Ù¸¥ ¿¡·¯¶ó¸é ¹®Á¦°¡ ÀÖ´Â °æ¿ìÀÌ´Ù.
1418                        dprint(1, "!! pre-scan PID tune err %d. continue..\n", status);
1419                        doDmc_ClearProgramInfo();
1420                        // prescan PID Á¤º¸¸¦ ¹«½ÃÇϰí Á¤»óÀûÀÎ ¹æ¹ýÀ¸·Î °è¼Ó ÁøÇàÇÑ´Ù.
1421
1422                        // cafrii 070718 add
1423                        ctx->pid_tune_fail_count++;
1424                        ctx->pid_tune_fail_time = DHL_OS_GetMsCount();
1425                                // ³ªÁß¿¡ ´Ù½Ã psip/psi·Î ½Ãµµ ÇÒ ¶§ pid°¡ µ¿ÀÏÇÏ¸é ´Ù½Ã ½ÃµµÇÒ Çʿ䰡 ¾ø¾î¼­.
1426                       
1427                        return status;
1428                }
1429
1430#if USE_PERF_MON
1431        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1);
1432#endif
1433                //
1434                // ƯÁ¤ ±â´ÉÀ» À§Çؼ­ ÇöÀç Àç»ýÁßÀÎ programÀÇ program_number¸¦ ½±°Ô ¾Ë ¼ö ÀÖ´Â
1435                // ¹æ¹ýÀÌ ÇÊ¿äÇÏ´Ù.
1436                // ±×·¯±â À§Çؼ­ tuning¿¡ Á÷Á¢ »ç¿ëµÇÁö ¾Ê¾Ò´ø ÆÄ¶ó¹ÌÅ͵鵵
1437                // ¸ðµÎ ProgramInfo¿¡ ±â·ÏÀ» ÇØ µÐ´Ù.
1438                // ´Ü ÀÌ Á¤º¸°¡ ÇöÀç ¼ö½ÅÁßÀÎ programÀÇ Á¤º¸¿Í µ¿ÀÏÇÏ´Ù´Â º¸ÀåÀº ÇÒ ¼ö ¾ø´Ù.
1439                // UCMÀÌ ¾ÆÁÖ ¿À·¡Àü¿¡ updateµÈ °æ¿ì¶ó¸é Ʋ¸± °¡´É¼ºµµ ÀÖ´Ù.
1440                //
1441               
1442                doDmc_UpdateProgramInfoDigital(tuneParam->rf, tuneParam->type, TUNE_METHOD_ByPIDs,
1443                                                        tuneParam->major, tuneParam->minor, 
1444                                                        tuneParam->progNumber,
1445                                                        tuneParam->vidPid, tuneParam->audPid, tuneParam->pcrPid, tuneParam->vidType, tuneParam->audType);
1446               
1447                // cafrii 040527 add comment
1448                // ÀÌ ¹æ½ÄÀÇ tuning¿¡¼­¸¸Å­Àº ÀÌ ½ÃÁ¡¿¡¼­ PTS ¼³Á¤À» ÇÒ ¼ö ¾ø´Ù. PMT¸¦ ¾ÆÁ÷ ¹ÞÁö ¸øÇ߱⠶§¹®.
1449                // PTS ¼³Á¤Àº ³ªÁß¿¡ PsiMonitor°¡ °¡µ¿µÈ ÈÄ PMT°¡ ¼ö½ÅµÇ¾úÀ»¶§ ÇÑ´Ù.
1450                //
1451                status = statusOK;
1452
1453        }
1454        else
1455                status = statusInvalidArgument;
1456       
1457        return status; 
1458}
1459
1460
1461
1462
1463
1464
1465void doDmc_ReturnTuneResult(void *pfnCompleted, STATUS status, 
1466                                                        UINT32 userparam, UINT32 additionalParam)
1467{
1468        DMC_FN_TUNE_COMPLETED fn;
1469        fn = (DMC_FN_TUNE_COMPLETED) pfnCompleted;
1470       
1471        if (fn) {
1472                dprint(2, "    return %s (%d, '%s') to caller..\n",
1473                        status ? "error" : "success", status, DMW_CDB_ErrString(status));
1474                fn(status, userparam, (AppRfTuneCallbackParam *) additionalParam);
1475        }
1476        else
1477                dprint(2, "    return %s (%d, '%s') skipped.\n",
1478                        status ? "error" : "success", status, DMW_CDB_ErrString(status));
1479}
1480
1481
1482STATUS doDmc_RfTuneAnalog(ChannelTuneContext *ctx)
1483{
1484        STATUS status;
1485        TuneParam *tuneParam = &ctx->param;     
1486        CaptureParam capParam;
1487
1488#if USE_PERF_MON
1489        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 0);
1490#endif
1491
1492        dprint(2, "\tstart analog video..\n");
1493
1494
1495// arzhna, 100129
1496// doDmc_Notify()·Î app¿¡ notify,
1497// app¿¡¼­ ó¸®ÇÏ¿© CARD¿¡ reportÇÑ´Ù.
1498// ±âÁ¸ÀÇ ·çƾÀº »èÁ¦
1499        //
1500        // DMC_NOTIFY_CaPmt event¸¦ º°µµ·Î ¸¸µé¾î ó¸®
1501                dprint(2, "\t Report CaPmt (NULL)\n");
1502        doDmc_Notify(DMC_NOTIFY_CaPmt, (UINT32)NULL);   
1503       
1504        memset(&capParam, 0, sizeof(capParam));
1505       
1506        capParam.input_video = eDHL_CAP_NTSC0_VIDEO;
1507        capParam.input_audio = eDHL_CAP_NTSC0_AUDIO;
1508       
1509        status = doDmc_StartAnalog(&capParam);
1510        if (status) {
1511                status = statusAnalogError;
1512                dprint(0, "!! err in start analog, err %d. stop!\n", status);
1513        }
1514        else {
1515                doDmc_UpdateProgramInfoAnalog(tuneParam->rf, 
1516                                        eDHL_CAP_NTSC0_VIDEO, eDHL_CAP_NTSC0_AUDIO);
1517               
1518                status = statusOK;
1519        }
1520
1521#if USE_PERF_MON
1522        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AV_START, 1);
1523#endif
1524
1525        return status;
1526}
1527
1528
1529STATUS doDmc_CmdRfTune(DmcMessage *pmsg)
1530{
1531        STATUS status;
1532       
1533        ChannelTuneContext context, *ctx = &context;
1534        TuneParam *tuneParam;
1535                // ÆÄ¶ó¹ÌÅÍ·Î °Ç³×Áö´Â tuneParamÀº »ç¿ë ÈÄ OS_Free½ÃÄÑ¾ß ÇÑ´Ù.
1536               
1537        dprint(1, "cmdRfTune: cid %d\n", pmsg->cancelId);
1538
1539        if (pmsg->param == 0) {
1540                dprint(0, "  !! tuneParam NULL! stop! no callback!!\n");
1541                return statusInvalidArgument;
1542        }
1543
1544#if USE_PERF_MON
1545        if (gDmcPMTune == 0) {
1546                gDmcPMTune = DHL_PerfMonInit("DmcTune", 1);
1547                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_TOTAL, PM_EV_Name[PM_EV_TUNE_TOTAL]);
1548                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_STOP, PM_EV_Name[PM_EV_TUNE_STOP]);
1549                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_LOCK, PM_EV_Name[PM_EV_TUNE_LOCK]);
1550                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_PSIP_LOAD, PM_EV_Name[PM_EV_TUNE_PSIP_LOAD]);
1551                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_PSI_LOAD, PM_EV_Name[PM_EV_TUNE_PSI_LOAD]);
1552                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_AV_START, PM_EV_Name[PM_EV_TUNE_AV_START]);
1553                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_VIDEO_START, PM_EV_Name[PM_EV_TUNE_VIDEO_START]);
1554                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_AUDIO_START, PM_EV_Name[PM_EV_TUNE_AUDIO_START]);
1555                DHL_PerfMonRegister(gDmcPMTune, PM_EV_TUNE_CALLBACK, PM_EV_Name[PM_EV_TUNE_CALLBACK]);
1556        }
1557#endif
1558
1559#if USE_PERF_MON
1560        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_TOTAL, 0);
1561#endif
1562
1563        memset(ctx, 0, sizeof(ChannelTuneContext));
1564       
1565        (ctx->param) = *(TuneParam *)pmsg->param;  // tune param backup
1566        ctx->rf = ctx->param.rf;
1567        ctx->program_number = ctx->param.progNumber;
1568
1569       
1570        Dmc_ParamHeapDeallocator(pmsg->param);
1571       
1572        tuneParam = &ctx->param;
1573
1574#if USE_PERF_MON
1575        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_STOP, 0);
1576#endif
1577       
1578        // ±âÁ¸ ºñµð¿À°¡ µ¿ÀÛÁßÀÌ¸é ´Ý´Â´Ù.
1579        doDmc_Stop();
1580
1581#if USE_PERF_MON
1582        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_STOP, 1);
1583#endif
1584
1585        if (Dmc_CheckCancel()) goto label_cancelled;
1586
1587        //----------------------------------------
1588        //
1589
1590#if USE_PERF_MON
1591        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_LOCK, 0);
1592#endif
1593
1594        #if 0 // cafrii 060630 delete
1595        if (! tuneParam->tuneRequired) {
1596                dprint(2, "\tskip tuner HAL tuning..\n");
1597        }
1598        else
1599        #endif
1600        {
1601                status = doDmc_RfTuneSetTuner(ctx);
1602                if (status)
1603                        goto label_end_tune;
1604        }
1605
1606#if USE_PERF_MON
1607        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_LOCK, 1);
1608#endif
1609
1610        if (tuneParam->flag & CTF_TunerSetOnly) {
1611                // Æ©³Ê ¼³Á¤¸¸ ¼öÇàÇ϶ó´Â ¿É¼ÇÀÌ´Ù.
1612                // ÀÌ ±â´ÉÀº POD ¸ðµå¿¡¼­ ChannelForceTune request°¡ ¿Ã °æ¿ì¿¡ »ç¿ëµÈ´Ù.
1613                //
1614                dprint(1, "  TunerSetOnly mode..\n");
1615               
1616                status = statusOK;
1617                goto label_end_tune;
1618        }
1619
1620        if (Dmc_CheckCancel()) goto label_cancelled;
1621       
1622        //----------------------------------------
1623        // NTSC tuning
1624       
1625        if (tuneParam->type == Modulation_NTSC)
1626        {
1627                status = doDmc_RfTuneAnalog(ctx);
1628               
1629                goto label_end_tune;  // ¾Æ³¯·Î±× ä³ÎÀº À̰ÍÀ¸·Î ¸ðµç ÀÛ¾÷ÀÌ ³¡³­´Ù.
1630        }
1631       
1632        Demux_tsdStart(Dmc_GetCurrentTsd(), 0);
1633       
1634        //----------------------------------------
1635        // cafrii 041201 add
1636        // POD mode ¿¡¼­´Â PID tuningÀ» »ç¿ëÇϱⰡ °ï¶õÇÔ.
1637        // ¸ÕÀú PMT¸¦ ¼ö½ÅÇÑ ´ÙÀ½ CA_PMT¸¦ POD¿¡ report¸¦ ÇÑ ´ÙÀ½¿¡ Æ©´×ÇØ¾ß Çϱ⠶§¹®.
1638        //
1639        {
1640                // bugfix. callback ¹Ì ±¸Çö½Ã µðÆúÆ®´Â normal mode.
1641                PodStatusParam status;
1642                status.isPodInserted = FALSE;
1643                doDmc_Notify(DMC_NOTIFY_IsPodInserted, (UINT32)&status);       
1644               
1645                if (status.isPodInserted) {
1646                dprint(2, "  cable card active mode.. force PSI tuning\n");
1647                goto label_try_psi;
1648        }
1649        }
1650
1651        //----------------------------------------
1652        // tune by PIDs..       
1653
1654        if (tuneParam->flag & CTF_SkipPrescanPidInfo) {
1655                dprint(3, "  skip prescan pids by user flag\n");
1656        }
1657        else {
1658                status = doDmc_RfTuneByPidOnly(ctx);
1659               
1660                if (status == statusCancelled)
1661                        goto label_cancelled;
1662                       
1663                else if (status == statusOK) {
1664                        doDmc_StartFinalPsiMonitor(TRUE);
1665                        goto label_end_tune;
1666                }
1667        }
1668
1669        //----------------------------------------
1670        // Å×À̺íÀ» ¼ö½ÅÇÑ´Ù.  TVCT, CVCT, PAT ¸ðµÎ ¼ö½Å.
1671        //
1672
1673        // cafrii 070427 move position
1674        //  psi only mode ¿¡¼­´Â vct¸¦ ¹Þ¾Æµµ »ç¿ëÇÏÁöµµ ¾ÊÀ¸¹Ç·Î
1675        //  °¢ÀÚ ÇÊ¿äÇÑ ¶§¿¡ pat/pmt¸¦ ¹Þµµ·Ï ÇÑ´Ù.
1676        //
1677        if ((tuneParam->flag & CTF_Mask_Tuning) == CTF_PSIOnly) {
1678                dprint(2, "\tPSI only modes..\n");
1679                goto label_try_psi;
1680        }
1681
1682       
1683#if USE_PERF_MON
1684        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSIP_LOAD, 0);
1685#endif
1686                       
1687        status = doDmc_DownloadTables(ctx);
1688
1689        if (status == statusCancelled)
1690                goto label_cancelled;
1691
1692#if USE_PERF_MON
1693        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_PSIP_LOAD, 1);
1694#endif
1695
1696       
1697        if (ctx->vct)
1698        {
1699                // ¼ö½ÅµÈ VCT¸¦ ÀÌ¿ëÇÏ¿© Æ©´×À» ½ÃµµÇÑ´Ù.
1700                //
1701                status = doDmc_RfTuneByVct(ctx);
1702       
1703                if (status == statusCancelled) {
1704                        goto label_cancelled;
1705                }
1706                else if (status == statusOK) {
1707                        doDmc_StartFinalPsiMonitor(TRUE);
1708                        goto label_end_tune;
1709                }
1710        }
1711
1712        // »ç¿ë °¡´ÉÇÑ Tuning Mode
1713        //     CTF_VCTOnly or CTR_Automatic or CTR_SemiAutomatic.
1714        //
1715        //  VCTOnly´Â VCT·Î ó¸®ÇÏ´Â µµÁß ¿¡·¯°¡ ¹ß»ýÇÏ¸é ±×³É ¿¡·¯·Î Áß´Ü.
1716        //  Automatic/SemiAutomaticÀÎ °æ¿ì´Â VCT¿¡¼­ ¿¡·¯°¡ ³ª¸é PSI·Î ³Ñ¾î°¡¼­ °è¼Ó ÁøÇà.
1717        //
1718
1719        if ((tuneParam->flag & CTF_Mask_Tuning) == CTF_VCTOnly) {
1720                // returnStatus °ªÀº ÀÌ¹Ì Àû´çÇÑ °ªÀ» °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù.
1721                // ÀÌ °ªÀÌ ±×´ë·Î callback¿¡ ¸®ÅϵȴÙ.
1722                goto label_end_tune;
1723        }
1724
1725        if ((tuneParam->flag & CTF_Mask_Tuning) == CTF_SemiAutomatic) {
1726                // semi automatic ¸ðµå¶ó¸é ÇöÀç ¾î¶² ¿¡·¯°ªÀ» °¡Áö°í ÀÖ´À³Ä¿¡ µû¶ó
1727                // ºÐ±â°¡ °áÁ¤µÈ´Ù.
1728                // ¶ÇÇÑ ÀÌ ¸ðµå´Â retry Ç÷¡±×¿Í ÇÔ²² »ç¿ëµÇ¸é Àǹ̰¡ ¾ø´Ù. ¹«½ÃµÈ´Ù.
1729                if ((tuneParam->flag & CTF_RetryOtherChannel) == 0 &&
1730                        (status == statusVideoError)) {
1731                        // ÀÌ¹Ì video decodingÀÌ ½ÃµµµÈ »óÅÂÀ̹ǷΠ´õÀÌ»ó ½ÃµµÇÏÁö ¾Ê´Â´Ù.
1732                        dprint(2, "\tsemiAuto, noRetry mode with videoError status. skip PSI mode\n");
1733                        goto label_end_tune;
1734                }
1735        }
1736
1737label_try_psi: //------------------------------------------------------------
1738
1739        // PAT, PMT¸¦ ÀÌ¿ëÇÏ¿© Æ©´×À» ½ÃµµÇÑ´Ù.
1740       
1741        status = doDmc_RfTuneByPsi(ctx);
1742
1743        if (status == statusCancelled) {
1744                goto label_cancelled;
1745        }
1746        else if (status == statusOK) {
1747                doDmc_StartFinalPsiMonitor(TRUE);
1748        }
1749        goto label_end_tune;
1750
1751
1752label_cancelled:
1753        status = statusCancelled;
1754        goto label_end_tune;
1755
1756
1757label_end_tune: //------------------------------------------------------------
1758
1759        // cafrii 060802 add
1760        //   statusCancelled ¸Þ½ÃÁö Àü´ÞÀº ¾ÆÁÖ Áß¿äÇÏ´Ù.
1761        //   ¸ðµç result °ª¿¡ ¿ì¼±Çؼ­ Àü´ÞµÇ¾î¾ß ÇÑ´Ù.
1762        //   ÇöÀç ¸ðµç tuning °ü·Ã ÀÛ¾÷ÀÌ °ÅÀÇ ´Ù ¼º°øÇß´Ù ÇÏ´õ¶óµµ
1763        //   user°¡ cancelÀ» ¿øÇϸé statusCancelled¸¦ ³Ñ°ÜÁà¾ß ÇÑ´Ù.
1764        //
1765        if (status != statusCancelled)
1766        {
1767                if (Dmc_CheckCancel()) {
1768                        dprint(0, "!! tuning cancelled at final stage. status %d -> %d\n",
1769                                                status, statusCancelled);
1770                        status = statusCancelled;
1771                }
1772        }
1773       
1774        if (1)
1775        {
1776                AppRfTuneCallbackParam returnParam;
1777                ProgramAVInfo *av;
1778               
1779                memset(&returnParam, 0, sizeof(AppRfTuneCallbackParam));
1780               
1781                av = Dmc_LockAVMutex();
1782               
1783                returnParam.program = av;
1784                returnParam.tuneParam = tuneParam;
1785                returnParam.vct = ctx->vct;
1786                       
1787                returnParam.pat = av->pat ? av->pat : ctx->pat;
1788                returnParam.pmt = av->pmt ? av->pmt : ctx->pmt;
1789                        // TuningÀ» Çϸ鼭 PAT/PMT°¡ Áغñ°¡ µÇ¾ú´Ù¸é av->pat/pmt¿¡ ÀúÀåµÇ¾î ÀÖÀ¸¹Ç·Î
1790                        // ±× °ªÀ» ³Ñ°ÜÁØ´Ù.
1791                        // Æ©´× Áß¿¡ ½ÇÆÐÇÑ °æ¿ì¶ó¸é ±×³É ctx ³»¿¡ ³²¾ÆÀÖÀ» °ÍÀÌ´Ù.
1792
1793                // cafrii 060804 add
1794                av->userParam = pmsg->userParam; 
1795                        // tune callbackÀÇ userparamÀ» ±â¾ïÇØ µÎ°í
1796                        // psi changed notification¿¡¼­ ÀÌ parameter¸¦ ³Ñ°ÜÁÖÀÚ.
1797               
1798#if USE_PERF_MON
1799        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_CALLBACK, 0);
1800#endif
1801
1802                doDmc_ReturnTuneResult((void *)pmsg->pfnCompleted, status, 
1803                                                pmsg->userParam, (UINT32)&returnParam);
1804
1805#if USE_PERF_MON
1806        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_CALLBACK, 1);
1807#endif
1808       
1809                Dmc_UnlockAVMutex();
1810               
1811        }
1812               
1813        if (ctx->vct) {
1814                dprint(2, "\t free ctx->vct 0x%x\n", ctx->vct);
1815                FreeAtscTable(ctx->vct);
1816        }
1817
1818        // pat, pmt°¡ dmc_pat/dmc_pmt·Î µî·ÏµÇ´Â °ÍÀº StartDigital ¿¡¼­ active ON µÇ´Â ¼ø°£ÀÌ´Ù.
1819        // tuneParam¿¡ pat/pmt°¡ ³²¾ÆÀÖ´Â °æ¿ì´Â tuning¿¡ ½ÇÆÐÇÑ °æ¿ìÀ϶§ÀÌ´Ù.
1820        //
1821        if (ctx->pat) {
1822                dprint(2, "\t free ctx->pat 0x%x\n", ctx->pat);
1823                FreePAT(ctx->pat);
1824        }
1825        if (ctx->pmt) {
1826                dprint(2, "\t free ctx->pmt 0x%x\n", ctx->pmt);
1827                FreePMT(ctx->pmt);
1828        }
1829
1830#if USE_PERF_MON
1831        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_TOTAL, 1);
1832#endif
1833
1834
1835        return status;
1836
1837}  // doDmc_CmdRfTune
1838
1839
1840
1841
1842
1843#if COMMENT
1844________(){}
1845#endif
1846
1847#if DMW_REGISTER_DEBUG_SYMBOL
1848
1849
1850static DHL_SymbolTable symbols[] =
1851{
1852        //---- functions
1853       
1854       
1855        //---- vars
1856        DHL_VAR_SYM_ENTRY(g_SignalThresholdForDigitalChannel),
1857
1858        DHL_VAR_SYM_ENTRY(gDmcTestSkipVctDownload),
1859       
1860};
1861
1862#endif
1863
1864void RegisterChannelTuneSymbols(void)
1865{
1866       
1867#if DMW_REGISTER_DEBUG_SYMBOL
1868        DHL_DBG_RegisterSymbols(symbols, DHL_NUMSYMBOLS(symbols));
1869#endif
1870
1871}
1872
1873
1874
Note: See TracBrowser for help on using the repository browser.