source: svn/newcon3bcm2_21bu/dst/dmw/src/Channel/DMW_ChannelAV.c @ 76

Last change on this file since 76 was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 89.5 KB
Line 
1/*
2        DMW_ChannelAV.c
3
4        DMW Middleware Channel AV decoding Module
5
6        Digital STERAM Technology, Inc.
7
8*/
9
10
11#include "DMW_Platform.h"
12
13
14
15
16        #include "DHL_OSAL.h"
17        #include "DHL_Demux.h"
18        #include "DHL_SYS.h"
19        #include "DHL_AVCAP.h"
20        #include "DHL_DBG.h"
21       
22        #define VideoContextIsAnalog(x) FALSE
23        #define DHL_AV_IsDigitalContext(x) TRUE
24       
25        #define SETRECT(rect, xx, yy, ww, hh) { \
26    (rect)->x = (xx); \
27    (rect)->y = (yy); \
28    (rect)->w = (ww); \
29    (rect)->h = (hh); \
30        }
31
32//#endif
33
34#include "DMW_Config.h"
35
36#include "DMW_Status.h"
37#include "DMW_Channel.h"
38
39#include "dmw_channel_priv.h"
40
41#include "DMW_ChannelDemux.h"
42#include "DMW_ChannelUtil.h"
43
44#include "DMW_ChannelPM.h" // Performance monitor
45
46#include "DMW_Timer.h"
47
48//#include <string.h>
49
50
51DHL_MODULE("$dmc", 2);
52
53
54#if COMMENT
55____Config____(){}
56#endif
57
58
59
60// 1 À̸é video unhide 󸮸¦ seqhdr ¼ö½Å ÀÌÈÄ·Î ¹Ì·ë.
61// ÇöÀç´Â 1¸¸ Å×½ºÆ® µÇ°í ÀÖÀ½.
62//
63#define DMC_DELAYED_VIDEO_SHOW 1
64
65
66
67// cafrii 071031 add
68//
69// Config Param: TRUE or FALSE
70//
71// 1 À̸é ÇÁ·Î±×·¥ÀÌ °©Àڱ⠻ç¶óÁø °æ¿ì
72// ´Ù¸¥ ÇÁ·Î±×·¥À¸·Î retry ÇÏÁö ¾Ê°í ¿ÏÀüÈ÷ Á¤Áö ½ÃŲ´Ù.
73//
74#define DMC_STOP_WHEN_PROGRAM_DISAPPEAR 0
75       
76
77// cafrii 100705 add
78// »õ·Î¿î DHL API ÀÎÅÍÆäÀ̽º·Î ÀÎÇÑ º¯°æ
79#define NEW_DHL_API 1
80
81
82#if 0 // NEW_DHL_API
83//
84//
85// Config Param: TRUE or FALSE
86//
87// TRUE À̸é waited audio start ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù.
88// ½ÇÁ¦·Î pid¸¸ ÀÖ°í audio ES°¡ ¾ø´Â bad streamÀÇ °æ¿ì
89// audio only check¸¦ ½±°Ô ¼öÇàÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª channel tuning ¼Óµµ´Â ¶³¾îÁø´Ù.
90//
91// cafrii 070528 chagne
92// audio°¡ ¾ø´Â stream üũ¸¦ Çϱâ À§Çؼ­ 1·Î ¼³Á¤.
93//
94// cafrii 080910
95// audio frame count check api Á¦°ø Àü±îÁö 0À¸·Î..
96// cafrii 080923, set to 1
97//
98// cafrii 081222 set to 0.
99// audio recovery code°¡ º°µµ·Î Á¦°ø ¾ÈµÇ¹Ç·Î 0.
100// driver ¾ÈÁ¤¼º¿¡ ¹®Á¦°¡ ¾ø´Ù¸é 0À» »ç¿ëÇÏ´Â °ÍÀÌ ´õ ÁÁÀ½.
101//
102int dmc_bUseAudioStartWait = 0;
103
104#endif
105
106
107
108//
109// Config Param: TRUE or FALSE
110//
111// Å×½ºÆ® º¯¼ö
112//
113// TRUE À̸é PsiMonitor¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù.
114// Psi monitor¸¦ ´Ù¸¥ task¿¡¼­ ´ã´çÇÒ °æ¿ì¿¡ À¯¿ëÇÏ°Ô »ç¿ëÇÒ¼öÀÖÀ½.
115//
116int gDmcTestNoPsiMonitor = 0;
117char *gDmcStringNoPsiMonitor = 
118        "******** !!!! DmcTest: PsiMonitor disabled !!!! ************\n";
119
120
121
122
123//
124// Config Param: 0 / 1
125//
126// ÀÌ flag°¡ 1À̸é Audio¸¦ Àç»ýÇÏÁö ¾Ê´Â´Ù. (Å×½ºÆ® ¿ëµµ)
127//
128int dmc_bRunWithoutAudio;
129
130//
131// Config Param: 0 / 1
132//
133// ÀÌ flag°¡ 1À̸é Video¸¦ Àç»ýÇÏÁö ¾Ê´Â´Ù. (Å×½ºÆ® ¿ëµµ)
134//
135int dmc_bRunWithoutVideo;
136
137
138
139//
140// Config Param: psiVersionChange (2) or psiCRCChange (3)
141//
142// PSI Monitor¸¦ ½ÃÀÛÇÒ ¶§ »ç¿ëµÉ update mode
143//
144// DMC¿¡¼­´Â Channel tuningÀÌ Á¾·áµÇ¸é Psi monitor¸¦ ½ÃÀÛÇϴµ¥
145// À̶§ ÁöÁ¤ÇÏ´Â update modeÀÌ´Ù. ÀϹÝÀûÀ¸·Î version change¸¦ »ç¿ëÇÏÁö¸¸
146// CRC change°¡ ´õ ´Ù¾çÇÑ º¯°æ »çÇ×À» ¼ö½ÅÇÒ ¼ö ÀÖ´Ù´Â ÀǰßÀÌ À־
147// CRC change¸¦ »ç¿ëÇϰí ÀÖ´Ù.
148//
149// cafrii 101208 change
150// pat´Â crc change¸¦, pmt´Â version change »ç¿ë.
151// ½ºÆ®¸²ÀÌ º¯°æµÉ ¶§ ¹öÀüÀº µ¿ÀÏÇϸ鼭 ³»¿ëÀÌ ´Ù¸¥ °æ¿ì¿¡ ´ëÀÀÇϱâ À§ÇÔ.
152// pat°¡ »õ·Î °»½ÅµÇ¸é pmt´Â ´Ù½Ã ½ÃÀÛÇϹǷΠpmt´Â ±×³É ver changeµµ ±¦ÂúÀ» µí..
153//
154tDHL_PSI_Update dmc_PatUpdateMode = ePSIUPDATE_CRCCHANGE;
155tDHL_PSI_Update dmc_PmtUpdateMode = ePSIUPDATE_VERCHANGE;
156
157
158
159//
160// Config Param: TRUE or FALSE
161//
162// PSI (Pat/Pmt) Change event ¹ß»ý½Ã "µ¿µî"ÇÑ Psi¸¦ ¹«½ÃÇÒ°ÍÀÎÁö ¿©ºÎ
163//
164// TRUEÀ̸é PSI change event°¡ ¹ß»ýÇ߾ equivalent PSI¶ó¸é
165// Àû¿ëÇÏÁö ¾Ê´Â´Ù.
166// PMT Equivalence Á¶°Ç: °¢Á¾ Elementary streamµéÀÇ PID°¡ °°Àº °æ¿ì
167// PAT Equivalence Á¶°Ç: program number, PMT PID°¡ µ¿ÀÏÇÑ °æ¿ì
168//
169BOOL dmc_bIgnoreEquivPat = TRUE;
170BOOL dmc_bIgnoreEquivPmt = TRUE;
171       
172
173
174//
175// Config Param: TRUE or FALSE
176//
177// PSI (Pat/Pmt) Change event ¹ß»ý½Ã "µ¿µî"ÇÑ Psi¸¦ ¹«½ÃÇÒ°ÍÀÎÁö ¿©ºÎ
178//
179// TRUEÀ̸é audio¸¦ ½ÃÀÛÇÒ ¶§ Àӽà mute¸¦ °É°í
180// ³ªÁß¿¡ video°¡ ³ª¿À±â ½ÃÀÛÇÒ ¶§ Àӽà mute¸¦ Ç®¾î¼­ µ¿±âÈ­ ½ÃŲ´Ù.
181//
182// ¿©±â¼­ »ç¿ëÇÏ´Â audio mute´Â »ç¿ëÀÚÀÇ audio mute, rating block muteµî°ú
183// °ãÄ¡Áö ¾Êµµ·Ï µ¶¸³ÀûÀÎ mute API¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.
184//
185// cafrii 080923,
186// video freeze event not support. so disable this.
187// for av_sync_start to work correctly,
188// freeze_end_event and audio_temp_mute should be supported.
189//
190// cafrii 100810, add for newby
191//
192BOOL dmc_bAudioVideoSyncStart = TRUE;
193
194
195
196//-----------------------------------------------------------
197
198
199#if COMMENT
200____Types____(){}
201#endif
202
203
204
205
206
207
208//-----------------------------------------------------------
209
210#if COMMENT
211____Variables____(){}
212#endif
213
214
215
216DMC_FN_USERDATA _Dmc_UserDataProc;
217        //
218        // ÀÌ ÇÔ¼ö Æ÷ÀÎÅͰ¡ À¯È¿Çϸé UserData°¡ ¹ß°ßµÉ ¶§ ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
219        // CC moduleÀÌ initializeµÉ ¶§ ÀÌ ÇÔ¼ö Æ÷ÀÎÅ͸¦ ÃʱâÈ­ ÇÏ¸é µÈ´Ù.
220
221
222
223
224
225int dmc_nPmtChangeRetryCount;
226        // PmtChange µµÁß¿¡ ¿¡·¯°¡ ³¯¶§ 1¾¿ Áõ°¡ÇÏ°í ´Ù½Ã Àç ½Ãµµ ÇÑ´Ù.
227int dmc_LimitPmtChangeRetryCount = 3; 
228        // ÀÌ ÀÌ»óÀ¸·Î error°¡ ³ª¸é PmtChange´Â Æ÷±âÇÑ´Ù.
229
230
231//-----------------------------------------------------------
232// PSI Management
233//
234// µðÁöÅРä³ÎÀÇ AV decoding ÀÌ µ¿ÀÛÁßÀÏ ¶§ ÇöÀç ä³ÎÀÇ PAT/PMT´Â Ç×»ó °¨½Ã¸¦ Çϰí
235// ¸¶Áö¸· Table instance´Â º¸°üÀÌ µÇ¾î ÀÖ´Ù.
236
237//MPEG_PAT   *av->pat = NULL;
238//MPEG_PMT   *av->pmt = NULL;
239
240// Dmc task¿¡¼­´Â PAT¿Í PMT¿¡ ´ëÇØ¼­ MonitoringÀ» ¼öÇàÇÑ´Ù.
241// µû¶ó¼­ ÀÌ PsiCtlµéÀÌ ÀÛµ¿ÁßÀÏ °æ¿ì¿¡´Â GetPAT³ª GetPMT°¡ µ¿ÀÛÇÏÁö ¾Ê´Â´Ù.
242// StartDigital() ¿¡¼­ºÎÅÍ StopDigital()ÀÌ ºÒ¸±¶§±îÁö monitor°¡ µ¿ÀÛÇÑ´Ù.
243//
244// ÀÌ ±¸°£Áß¿¡ ²À GetPAT/PMT()¸¦ »ç¿ëÇÒ Çʿ䰡 ÀÖÀ»¶§´Â
245// PausePsiMonitor/ResumePsiMonitor¸¦ »ç¿ëÇϵµ·Ï ÇÏÀÚ.
246//
247//PSIControl *av->patPsiCtl = NULL;
248//PSIControl *av->pmtPsiCtl = NULL;
249
250
251
252
253
254//tDHL_VideoSeqHdr dmc_SeqHdr;
255        // ÇöÀç µðÄÚµù µÇ°í ÀÖ´Â Video streamÀÇ sequence header Á¤º¸
256       
257
258//-----------------------------------------------------------
259// ¾Æ·¡ º¯¼öµéÀº ¸ðµÎ mutex lock »óÅ¿¡¼­ Á¢±ÙÇØ¾ß ÇÑ´Ù.
260//
261
262static ProgramAVInfo s_programinfo;
263        //
264        // ÇöÀç ½ÃûÁßÀÎ ÇÁ·Î±×·¥¿¡ ´ëÇÑ Á¤º¸
265        //
266       
267
268
269
270
271DHL_OS_SEMA_ID dmc_psiSema4;
272        //
273        // av->pat/pmt, pat/pmt psi control µîÀÇ º¯¼ö¸¦ º¸È£ÇÏ´Â mutex
274       
275DHL_OS_SEMA_ID dmc_avSema4;
276        //
277
278
279BOOL dmc_bWaitFirstFreezeVideoEndEvent = FALSE;
280        // video¸¦ óÀ½ ½ÃÀÛÇϸé ÀÌ º¯¼ö¸¦ setÇϰí
281        // óÀ½ freeze end°¡ ¿ÔÀ»¶§ callbackÀ» ÇØÁØ´Ù.
282
283
284
285
286DMC_FN_NOTIFY _Dmc_Notify;
287        //
288        // applicationÀ¸·Î notify Çϱâ À§ÇÑ callback ÇÔ¼ö.
289        // notify µÇ´Â eventµé..
290
291
292DMC_FN_NOTIFY _Dmc_DecodeStartCallback;
293DMC_FN_NOTIFY _Dmc_DecodeStopCallback;
294        // 1394 PTS¸¦ À§ÇÑ callback handler.
295        // 
296        // µðÄÚµù óÀ½ ½ÃÀ۽à PMT°¡ »õ·Î ¼ö½ÅµÇ¾úÀ» ¶§,
297        // µðÄÚµùÀÌ ÁøÇà Áß¿¡ PMT°¡ »õ·Î updateµÇ¾úÀ» ¶§¿¡ ºÒ¸°´Ù.
298        //
299        // param1 : ÇöÀç µðÄÚµù ÁßÀÎ ÇÁ·Î±×·¥ÀÇ program number
300        // param2 (bThisPmtIsIgnoredInDmc) : DMC¿¡¼­ ÀÌ PMT°¡ ignoreµÈ °ÍÀ̶ó¸é TRUE
301        //         DMC¿¡¼­ ignore°¡ µÇ¾ú´õ¶óµµ callbackÀº ºÒ¸°´Ù.
302        //
303        // DecodeStopCallbackÀº VideoStopÀÌ µÉ ¶§ ºÒ¸®´Â callbackÀ¸·Î PTS ÁßÁö ÀÛ¾÷ µîÀ» À§ÇÔÀÌ´Ù.
304        //  ÀÌ callbackÀÇ parameter´Â ¾ÆÁ÷ undefined ÀÌ´Ù.
305
306
307
308
309UINT8 dmc_bRequestVideoHide;
310        // ºñµð¿À Hide request°¡ µé¾î¿À¸é ÀÌ flag°¡ TRUEÀÌ´Ù.
311        //
312        // BOOL ¿¡¼­ UINT8 ·Î º¯°æ ÇÏ¿´À¸¸ç, bit flag·Î »ç¿ëÇÑ´Ù.
313       
314
315
316#define TIMER_ID_AUDIO_TEMPMUTE_LIMIT 9191
317        // ´Ù¸¥ id¿Í °ãÄ¡¸é ¾ÈµÇ´Ï app ¿¡¼­ °ü¸®ÇÏ´Â °ÍÀÌ ÁÁÀºµ¥..
318        // ÀÏ´Ü À̰÷¿¡¼­ ÀÓÀÇ °ª Á¤Çؼ­ »ç¿ëÇϱâ·Î ÇÔ.
319
320
321int g_AudioTempMuteLimitMs = 3000;
322        // av sync start ±â´É¿¡¼­ Ȥ½Ã video¿¡ ¹®Á¦°¡ À־ audio temp unmute¸¦ ÇÏÁö ¸øÇÏ´Â
323        // ¹®Á¦¿¡ ´ëºñÇϱâ À§Çؼ­ timeoutÀ» °É¾îµÎ´Âµ¥, ±× timeout ½Ã°£.
324        // ´ÜÀ§´Â millisec.
325        //
326
327       
328
329#if COMMENT
330________Debug________(){}
331#endif
332
333
334
335BOOL g_Trace_bDmcPsiEvent = 0;
336        // PAT/PMT Hanlder¿¡ °ü·ÃµÈ ¸Þ½ÃÁö.. ÀÌ flag´Â TRUE/FALSE ¸¸ ÁöÁ¤ °¡´É.
337        // ÀÌ trace flag´Â g_Trace_DmcMain ¿¡ ÀÇÇØ ´Ù½ÃÇѹø check µÇ±â ¶§¹®¿¡
338        // true¸¦ ÇÏ´õ¶óµµ g_Trace_DmcMainÀÌ ³·Àº °ªÀ̸é Ãâ·ÂÀÌ µÇÁö ¾ÊÀ» ¼ö ÀÖÀ½.
339
340
341
342
343
344
345
346
347
348// ÇöÀç video formatÀ» ¾Ë¾Æ³»´Â utility
349//
350
351void Dmc_ShowSeqHeader(int level, tDHL_VideoSeqHdr *seq)
352{
353        char *chroma[4] = { "Unknown", "4:2:0", "4:2:2", "4:4:4" };
354       
355        if (seq == NULL) return;
356
357        dprint(level, "tDHL_VideoSeqHdr %x, %s format\n", seq);
358       
359        dprint(level, "\thorz: %d, vert:%d, framerate %5.2f, aspect_ratio %d (%s)\n",
360                        seq->horizontal_size, seq->vertical_size, seq->frame_rate,
361                        seq->aspect_ratio_information, 
362                        DHL_AV_IsWideoFormat(seq) ? "wide" : "narrow");
363        dprint(level, "\tbitrate %d, vbv buffer %d, constrained param %d, MPEG%d\n",
364                        seq->bit_rate, seq->vbv_buffer_size, seq->constrained_parameter_flag, seq->MPEG2 ? 2 : 1);
365        dprint(level, "\tprofile %d, %s, chroma %s, low delay %d\n",
366                        seq->profile_and_level_indication, seq->progressive_sequence ? "progressive" : "interlace",
367                        chroma[seq->chroma_format & 3], seq->low_delay);
368}
369
370STATUS Dmc_PrintVideoFormat(int level, BOOL bDisplayBrief)
371{
372        tDHL_VideoSeqHdr seq;
373        BOOL bWide;
374
375        DHL_RESULT dhlResult = DHL_AV_VideoSeqInfo(0, &seq);
376
377
378        if (dhlResult) {
379                dprint(0, "!! Dmc_PrintVideoFormat: no valid seq hdr.\n");
380                return statusError;
381        }
382
383        bWide = DHL_AV_IsWideoFormat(&seq);
384
385        if (bDisplayBrief) {
386                dprint(level, "\tsource: %4dx%4d %c %5.2fHz %s\n",
387                        seq.horizontal_size, seq.vertical_size,
388                        seq.progressive_sequence ? 'p' : 'i',
389                        seq.frame_rate, bWide ? "wide" : "narrow");
390        }
391        else {
392                Dmc_ShowSeqHeader(level, &seq);
393        }
394       
395        return (STATUS)0;
396}
397
398void Dmc_PrintProgramInfo(int dbglevel)
399{
400        ProgramAVInfo *av = Dmc_LockAVMutex();
401       
402        // cafrii 041103 add 'dbglevel' argument
403       
404        if (av->active) 
405        {
406                dprint(dbglevel, "\t%s \n", av->analog ? "Analog" : "Digital");
407                       
408                if (av->analog) {
409                        if (av->input_video == eDHL_CAP_NTSC0_VIDEO ||
410                                av->input_video == eDHL_CAP_NTSC1_VIDEO)
411                                dprint(dbglevel, "\tNTSC, RF: %d\n", av->rf);
412
413                        else
414                                dprint(dbglevel, "\tExt, video %d, audio %d\n", 
415                                                av->input_video, av->input_audio);
416                }
417                else if (av->method == TUNE_METHOD_ByPIDs)
418                        dprint(dbglevel, "\tRF %d, Method: by PIDs, #%d, p%d v%d a%d\n", 
419                                                av->rf, av->program_number,
420                                                av->pcr_pid, av->video_pid, av->audio_pid);
421                                               
422                else if (av->method == TUNE_METHOD_ByCVCT)
423                        dprint(dbglevel, "\tRF %d, Method: by CVCT, %d-%d, #%d, p%d v%d a%d\n", 
424                                                av->rf, av->major, av->minor,
425                                                av->program_number,
426                                                av->pcr_pid, av->video_pid, av->audio_pid);
427                                               
428                else if (av->method == TUNE_METHOD_ByTVCT)
429                        dprint(dbglevel, "\tRF %d, Method: by TVCT, %d-%d, #%d, p%d v%d a%d\n", 
430                                                av->rf, av->major, av->minor,
431                                                av->program_number,
432                                                av->pcr_pid, av->video_pid, av->audio_pid);
433                                               
434                else if (av->method == TUNE_METHOD_ByPSI)
435                        dprint(dbglevel, "\tRF %d, Method: by PSI, #%d, p%d v%d a%d\n", 
436                                                av->rf, av->program_number,
437                                                av->pcr_pid, av->video_pid, av->audio_pid);             
438                else
439                        dprint(dbglevel, "\tUnknown method!\n");
440               
441        }
442        else dprint(dbglevel, "\tNot tuned!! (inactive)\n");   
443
444        dprint(dbglevel, "\tfreeze %s, hidden %s\n",
445                av->video_freezed ? "ON" : "Off",
446                av->video_hidden ? "ON" : "Off");
447
448        dprint(dbglevel, "\tpat 0x%x, pmt 0x%x\n", av->pat, av->pmt);
449#if USE_CH_MW_ALL_PMT_DOWNLOAD
450        if (1) {
451                int i;
452                for (i=0; av->pat && av->pmtList && i<av->pat->numPrograms; i++)
453                        dprint(dbglevel, "\t  pmt[%d] 0x%x\n", i, av->pmtList[i]);
454        }
455#endif
456        dprint(dbglevel, "\tpatPsiCtl 0x%x, pmtPsiCtl 0x%x\n", av->patPsiCtl, av->pmtPsiCtl);
457#if USE_CH_MW_ALL_PMT_DOWNLOAD
458        dprint(dbglevel, "\t  pmtPsiCtl2 0x%x\n", av->pmtPsiCtl2);
459#endif
460        dprint(dbglevel, "\tFN_Notify %x\n", _Dmc_Notify);
461       
462        Dmc_UnlockAVMutex();
463
464}
465
466
467
468
469#if COMMENT
470_______Utils________(){}
471#endif
472
473
474/*
475        DMC tuning taskÀÇ ÇÙ½É Á¤º¸ ±¸Á¶Ã¼ÀÎ ProgramAVInfo Á¤º¸¸¦
476        ÂüÁ¶ÇÒ ¶§´Â lock/unlockÀ» ÇØ¾ß ÇÑ´Ù.
477*/
478
479ProgramAVInfo *Dmc_LockAVMutex()
480{
481        DHL_OS_TakeSemaphore(dmc_avSema4, DHL_TIMEOUT_FOREVER);
482        return &s_programinfo;
483}
484
485void Dmc_UnlockAVMutex(void)
486{
487        DHL_OS_GiveSemaphore(dmc_avSema4);
488}
489
490
491// Dmc_GetCurrentProgramInfo
492//    DMC ÀÇ Program Á¤º¸¸¦ ³Ñ°ÜÁØ´Ù.
493//    ProgramÀº DMCÀÇ °¢Á¾ »óÅ Á¤º¸°¡ µé¾îÀÖ´Â ¾ÆÁÖ Áß¿äÇÑ Á¤º¸ÀÌ´Ù.
494//
495void Dmc_GetCurrentProgramInfo(ProgramAVInfo *av1)
496{
497        ProgramAVInfo *av2 = Dmc_LockAVMutex();
498
499        memcpy(av1, av2, sizeof(ProgramAVInfo));
500       
501        Dmc_UnlockAVMutex();
502}
503
504
505
506// Dmc_GetCurrentProgramNumber
507//    ÇöÀç µðÄÚµù ÁßÀÎ Program number¸¦ µÇµ¹·ÁÁØ´Ù.
508//    Program Á¤º¸¸¦ ÀÌ¿ëÇØ¼­ ¾Ë ¼öµµ ÀÖ´Ù.
509//    0À̸é ÇÁ·Î±×·¥ ¹øÈ£¸¦ ¾Ë¼ö ¾ø´Â »óŸ¦ ÀǹÌÇÑ´Ù.
510//
511int Dmc_GetCurrentProgramNumber()
512{
513        int program_number;
514        ProgramAVInfo *av = Dmc_LockAVMutex();
515       
516        if (av->active) {
517                if (av->analog) 
518                        program_number = 0;   // ¾Æ³¯·Î±× »óÅ¿¡¼­ program number´Â Àǹ̰¡ ¾øÀ½.
519                else
520                        program_number = av->program_number;
521        }
522        else
523                program_number = 0;  // decoder°¡ Á¤Áö »óÅ¿¡¼­µµ program number´Â Àǹ̰¡ ¾øÀ½.
524               
525        Dmc_UnlockAVMutex();
526               
527        return program_number;
528}
529
530
531
532
533
534// Dmc_GetVideoSequenceHeader
535//   Video sequence header Á¤º¸¸¦ ³Ñ°ÜÁØ´Ù.
536//   ¾øÀ¸¸é FALSE¸¦ ¸®ÅÏÇÑ´Ù.
537//
538BOOL Dmc_GetVideoSequenceHeader(tDHL_VideoSeqHdr *pSeq)
539{
540        DHL_RESULT dhlResult;
541       
542        if (pSeq == NULL) 
543                return FALSE;
544
545        dhlResult = DHL_AV_VideoSeqInfo(0, pSeq);
546
547        return dhlResult ? FALSE : TRUE;
548}
549
550
551
552
553#if COMMENT
554_______ProgramInfo________(){}
555#endif
556
557
558
559void doDmc_ClearProgramInfo()
560{
561        ProgramAVInfo *av = Dmc_LockAVMutex();
562        av->active  = FALSE;
563        Dmc_UnlockAVMutex();
564}
565
566//
567// tuningÀÌ ³¡³­ ÈÄ¿¡ ÇöÀç »óŸ¦ Program ±¸Á¶Ã¼¿¡ ÀúÀåÇÑ´Ù.
568//
569void doDmc_UpdateProgramInfoDigital(int rf, ModulationType mod, TUNE_METHOD method, 
570                                                        int major, int minor, int program_number,
571                                                        UINT16 vidPid, UINT16 audPid, UINT16 pcrPid, tDHL_VideoCodingType vidType, tDHL_AudioCodingType audType)
572{
573        ProgramAVInfo *av = Dmc_LockAVMutex();
574       
575        av->active  = TRUE;
576        av->analog  = FALSE; // digital
577
578        av->rf = rf;
579        av->mod = mod;
580       
581        av->method  = method;
582        av->major   = major;
583        av->minor   = minor;
584        av->program_number = program_number;
585
586        av->video_pid = vidPid;
587        av->audio_pid = audPid;
588        av->pcr_pid = pcrPid;
589        av->video_type = vidType;
590        av->audio_type = audType;
591       
592        av->input_video = eDHL_CAP_DTV_TS0;
593        av->input_audio = eDHL_CAP_DTV_TS0_AUDIO;
594
595        Dmc_UnlockAVMutex();
596}
597
598void doDmc_UpdateProgramInfoAnalog(int rf, 
599                                tDHL_CapVideoInput video, tDHL_CapAudioInput audio)
600{       
601        ProgramAVInfo *av = Dmc_LockAVMutex();
602       
603        av->active  = TRUE;
604        av->analog  = TRUE;
605
606        av->rf = rf;
607        av->mod = Modulation_NTSC;
608       
609        av->input_video = video;
610        av->input_audio = audio;
611        av->method  = TUNE_METHOD_NONE;
612        av->major   = 0;
613        av->minor   = 0;
614        av->program_number = 0;
615
616        Dmc_UnlockAVMutex();
617}
618
619
620
621
622//
623//
624// »õ·Ó°Ô ¼ö½ÅÇÑ pat/pmt¸¦ AVINFO¿¡ ÀúÀåÇÑ´Ù.
625//
626void doDmc_UpdatePsiInfo(MPEG_PAT *pat, MPEG_PMT *pmt)
627{
628        ProgramAVInfo *av = Dmc_LockAVMutex();
629#if DMC_CHECK_HEAP_SIZE
630        UINT32 heap_before;
631#endif
632
633        if (pat) {
634                if (av->pat) {
635#if USE_CH_MW_ALL_PMT_DOWNLOAD
636                        // pat°¡ »õ·Ó°Ô °»½ÅÇÏ¸é ¸ðµç pmt µéµµ ´Ù replace µÇµµ·Ï ÇÑ´Ù.
637                        int i;
638                        for (i=0; i<av->pat->numPrograms; i++) {
639                                if (av->pmtList[i]) {
640                                        //dprint(2, "######## free pmt[%d] %x\n", i, av->pmtList[i]);
641                                        FreePMT(av->pmtList[i]);
642                                }
643                        }
644                        if (av->pat->numPrograms != pat->numPrograms) {
645                                dprint(2, "num programs changed %d -> %d\n", av->pat->numPrograms, pat->numPrograms);
646                                DHL_OS_Free((void **)&av->pmtList);
647                        }
648#endif
649               
650#if DMC_CHECK_HEAP_SIZE
651                        heap_before = DHL_GetFreeHeapSize(0);
652#endif
653                        FreePAT(av->pat);  // tuning¿¡ ¼º°øÇϸé pat/pmt¿¡ ¹Ù·Î updateÇÑ´Ù.
654
655#if DMC_CHECK_HEAP_SIZE
656                        dprint(3, "free prev pat %x, heap %u->%u\n", av->pat, 
657                        heap_before, DHL_GetFreeHeapSize(0));
658#else
659                        dprint(3, "free prev pat %x\n", av->pat);
660#endif
661                }
662                av->pat = pat;
663
664#if USE_CH_MW_ALL_PMT_DOWNLOAD
665                if (av->pmtList == NULL)
666                        av->pmtList = DHL_OS_Malloc(av->pat->numPrograms * sizeof(MPEG_PMT *));
667                if (av->pmtList == NULL)
668                        dprint(0, "!! out of mem for pmtlist\n");
669                else
670                        memset(av->pmtList, 0, av->pat->numPrograms * sizeof(MPEG_PMT *));
671#endif
672        }
673       
674        if (pmt) {
675                if (av->pmt) {
676#if DMC_CHECK_HEAP_SIZE
677                        heap_before = DHL_GetFreeHeapSize(0);
678#endif
679                        FreePMT(av->pmt);
680#if DMC_CHECK_HEAP_SIZE
681                        dprint(3, "free prev pmt %x, heap %u->%u\n", av->pmt, 
682                        heap_before, DHL_GetFreeHeapSize(0));
683#else
684                        dprint(3, "free prev pmt %x\n", av->pmt);
685#endif
686                }
687                av->pmt = pmt;
688        }
689       
690        Dmc_UnlockAVMutex();
691}
692       
693
694
695
696#if COMMENT
697____EventProc____(){}
698#endif
699
700
701
702
703static void _Dmc_SendDecodeEvent(DmcMsgType msgtype, UINT32 userParam)
704{
705        STATUS status;
706       
707        status = Dmc_SendCommandEx(msgtype, 
708                                                        userParam,
709                                                        NULL,
710                                                        FALSE,    // "NO" wait for complete
711                                                        NULL, 0,  // user callback&param
712                                                        FALSE);   // do not cancel previous command
713
714        if (status)
715                dprint(0, "!! send event err %d\n", status);
716               
717        // send message¿¡ ¿¡·¯ ¹ß»ý½Ã Ưº°È÷ ¿¡·¯Ã³¸®¸¦ ÇÒ ÀÏÀº ¾ø´Ù
718}
719
720
721//-----------------------------------------------------------------------------
722// ¾Æ·¡ _Dmc_xxx Äݹé ÇÔ¼öµéÀº driver task¿¡¼­ ¹Ù·Î ºÒ¸®±â ¶§¹®¿¡
723// high priority À̰í, À̰÷¿¡¼­ ¸¹Àº ÀÏÀ» ÇÏÁö ¾Êµµ·Ï ÇÑ´Ù.
724//
725void _Dmc_PatEventProc(tDHL_PSI_Event psiEvent, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam)
726{
727        STATUS status;
728        DHL_RESULT err;
729        tDHL_PSI_DataArray *desc;
730        MPEG_PAT *pat;
731        DmcMessage msg;
732
733#if DMC_CHECK_HEAP_SIZE
734        UINT32 heap_before;
735#endif
736
737        // comment: userParamÀº »ç¿ëµÇÁö ¾Ê´Â´Ù.
738       
739        memset(&msg, 0, sizeof(msg));
740
741        if (psiEvent == ePSIEVENT_DATARECEIVED) {
742                // data recieved event´Â debug printÇÏÁö ¾Ê´Â´Ù.
743                //
744                err = DHL_PSI_ReadPSIData(psiCtl, &desc);
745                if (err) {
746                        dprint(0, "_Dmc_PatEventProc: DHL_PSI_ReadPSIData returned %s\n", ErrorString(err));
747                        return;
748                }
749
750#if DMC_CHECK_HEAP_SIZE
751                heap_before = DHL_GetFreeHeapSize(0);
752#endif
753
754                err = ParsePAT(desc, &pat);
755                DHL_PSI_FreePSIData(desc);
756                if (IsError(err)) { // cafrii 050315 change
757                        dprint(0, "_Dmc_PatEventProc: ParsePAT returned %s\n",ErrorString(err));
758                        return;
759                }
760
761        #if 0
762                // cafrii 060303
763                // ÀÌÁ¦ºÎÅÍ´Â pat/pmt¿¡ Á¢±ÙÇϱâ À§Çؼ­´Â mutex¸¦ lock ÇØ¾ß Çϴµ¥,
764                // ÀÌ task¿¡¼­ lockÀ» ÇÏ´Â °ÍÀº À§ÇèÇÒ ¼ö ÀÖ´Ù.
765                // descriptor ÀÚü¸¦ ÀúÀåÇÏ´Â ´Ù¸¥ ¹æ¹ýÀ» °í·ÁÇØº¸µµ·Ï ÇÏÀÚ.
766               
767                // Note!!
768                // ÀÌ Å½ºÅ©´Â TSDXX ·Î Dmc task°¡ ¾Æ´Ï±â ¶§¹®¿¡ pat/pmt¸¦ ¿©±â¼­ ÂüÁ¶ÇÏ´Â °ÍÀº
769                // ¾ÈÀüÇÏÁö ¸øÇÒ ¼öµµ ÀÖ´Ù..
770                //
771                if (Dmc_CheckIfSamePat(pat, av->pat)) { // cafrii 040529 add
772                        if (av->pmt && av->pmtPsiCtl) {  // cafrii 040604 add av->pmtPsiCtl
773                                if (g_Trace_bDmcPsiEvent)
774                                        dprint(2, "_Dmc_PatEventProc: Same PAT\n");
775                                FreePAT(pat);
776                                return;
777                        }
778                        else {
779                                //if (g_Trace_bDmcPsiEvent)
780                                //      dprint(2, "_Dmc_PatEventProc: Same PAT.. notify to DMC\n");
781                                // PMT°¡ ¾ø´Â °æ¿ì¿¡´Â ºñ·Ï °°Àº PAT°¡ ¼ö½ÅµÇ¾ú´Ù ÇÏ´õ¶óµµ Dmc¿¡ ¾Ë·ÁÁà¾ß ÇÑ´Ù.
782                        }
783                }
784        #endif
785               
786                if (g_Trace_bDmcPsiEvent) {
787
788#if DMC_CHECK_HEAP_SIZE
789                        dprint(2, "New PAT: TSID %d, v%d, %d programs, 0x%x, heap: %u->%u\n",
790                                pat->transport_stream_id, pat->version_number, pat->numPrograms,
791                                pat, heap_before, DHL_GetFreeHeapSize(0));
792#else
793                        dprint(2, "New PAT: TSID %d, v%d, %d programs\n",
794                                pat->transport_stream_id, pat->version_number, pat->numPrograms);
795#endif
796                }
797        }
798        else {
799                // cafrii 030901, add           
800                if (g_Trace_bDmcPsiEvent) {
801                        if (psiEvent != ePSIEVENT_LOSTPACKET)
802                                dprint(3, "_Dmc_PatEventProc: psiEvent %s\n", DHL_PSIEventString(psiEvent));
803                }
804                return;
805        }
806
807        status = Dmc_SendCommandEx(evtPatChange, 
808                                                        (UINT32)pat,
809                                                        (DMC_FN_CANCELFREE)FreePAT,
810                                                        FALSE,    // "NO" wait for complete
811                                                        NULL, 0,  // user callback&param
812                                                        FALSE);   // do not cancel previous command
813
814        if (status) {
815                // DMC Q°¡ overflowµÇ¾î µé¾î°¡Áö ¾Ê¾Ò±â ¶§¹®¿¡
816                // ÇÒ´çÇÑ Å×À̺íÀ» »èÁ¦Çؼ­ ¸Þ¸ð¸® ´©¼ö¸¦ ¸·´Â´Ù
817                if (g_Trace_bDmcPsiEvent)
818                        dprint(0, "!!_Dmc_PatEventProc: DmcQ full\n"); 
819               
820                //neverdai. 081110 À§ ÇÔ¼ö¿¡¼­ ¿¡·¯°¡ »ý±â¸é FreePAT¸¦ È£ÃâÇϱ⠶§¹®¿¡
821                //µû·Î FreePAT¸¦ È£ÃâÇÏ¸é ¹®Á¦ »ý±æ ¼ö ÀÖÀ½.
822                //FreePAT(pat);
823        }
824}
825
826void _Dmc_PmtEventProc(tDHL_PSI_Event psiEvent, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam)
827{
828        STATUS status;
829        DHL_RESULT err;
830        tDHL_PSI_DataArray *desc;
831        MPEG_PMT *pmt;
832        DmcMessage msg;
833
834#if DMC_CHECK_HEAP_SIZE
835        UINT32 heap_before;
836#endif
837
838        // comment: userparamÀº »ç¿ëµÇÁö ¾Ê´Â´Ù.
839       
840        memset(&msg, 0, sizeof(msg));
841
842        if (psiEvent == ePSIEVENT_DATARECEIVED) {
843                err = DHL_PSI_ReadPSIData(psiCtl, &desc);
844                if (err) {
845                        dprint(0, "_Dmc_PmtEventProc: DHL_PSI_ReadPSIData returned %s\n",ErrorString(err));
846                        return;
847                }
848
849#if DMC_CHECK_HEAP_SIZE
850                heap_before = DHL_GetFreeHeapSize(0);
851#endif
852                err = ParsePMT(desc, &pmt);
853                DHL_PSI_FreePSIData(desc);
854                if (IsError(err)) { // cafrii 050315 change
855                        dprint(0, "_Dmc_PmtEventProc: ParsePMT returned %s\n",ErrorString(err));
856                        return;
857                }
858
859        #if 0
860                // cafrii 060303
861                // ÀÌÁ¦ºÎÅÍ´Â pat/pmt¿¡ Á¢±ÙÇϱâ À§Çؼ­´Â mutex¸¦ lock ÇØ¾ß Çϴµ¥,
862                // ÀÌ task¿¡¼­ lockÀ» ÇÏ´Â °ÍÀº À§ÇèÇÒ ¼ö ÀÖ´Ù.
863                // descriptor ÀÚü¸¦ ÀúÀåÇÏ´Â ´Ù¸¥ ¹æ¹ýÀ» °í·ÁÇØº¸µµ·Ï ÇÏÀÚ.
864
865                // Note!!
866                // ÀÌ Å½ºÅ©´Â TSDXX ·Î Dmc task°¡ ¾Æ´Ï±â ¶§¹®¿¡ av->pat/pmt¸¦ ¿©±â¼­ ÂüÁ¶ÇÏ´Â °ÍÀº
867                // ¾ÈÀüÇÏÁö ¸øÇÒ ¼öµµ ÀÖ´Ù..
868                //
869                if (Dmc_CheckIfSamePmt(pmt, av->pmt)) {
870                        if (g_Trace_bDmcPsiEvent)
871                                dprint(2, "_Dmc_PmtEventProc: Same PMT\n");
872                        FreePMT(pmt);
873                        return;
874                }
875        #endif
876       
877                if (g_Trace_bDmcPsiEvent) {
878#if DMC_CHECK_HEAP_SIZE
879                        dprint(2, "New PMT: PID %d, #%d, v%d, PCR %d, 0x%x, heap %u->%u\n",
880                                pmt->PID, pmt->program_number, pmt->version_number, pmt->PCR_PID, 
881                                pmt, heap_before, DHL_GetFreeHeapSize(0));
882#else
883                        dprint(2, "New PMT: PID %d, #%d, v%d, PCR %d\n",
884                                pmt->PID, pmt->program_number, pmt->version_number, pmt->PCR_PID);
885#endif
886                }
887        }
888        else {
889                // cafrii 030918, add           
890                if (g_Trace_bDmcPsiEvent) {
891                        if (psiEvent != ePSIEVENT_LOSTPACKET)
892                                dprint(3, "_Dmc_PmtEventProc: psiEvent %s\n",DHL_PSIEventString(psiEvent));
893                }
894                return;
895        }
896
897        status = Dmc_SendCommandEx(evtPmtChange, 
898                                                        (UINT32)pmt,
899                                                        (DMC_FN_CANCELFREE)FreePMT,
900                                                        FALSE,    // "NO" wait for complete
901                                                        NULL, 0,  // user callback&param
902                                                        FALSE);   // do not cancel previous command
903
904        if (status) {
905                // DMC Q°¡ overflowµÇ¾î µé¾î°¡Áö ¾Ê¾Ò±â ¶§¹®¿¡
906                // ÇÒ´çÇÑ Å×À̺íÀ» »èÁ¦Çؼ­ ¸Þ¸ð¸® ´©¼ö¸¦ ¸·´Â´Ù
907                if (g_Trace_bDmcPsiEvent)
908                        dprint(0, "!!_Dmc_PmtEventProc: DmcQ full\n"); 
909                       
910                //neverdai. 081110 À§ ÇÔ¼ö¿¡¼­ ¿¡·¯°¡ »ý±â¸é FreePAT¸¦ È£ÃâÇϱ⠶§¹®¿¡
911                //µû·Î FreePAT¸¦ È£ÃâÇÏ¸é ¹®Á¦ »ý±æ ¼ö ÀÖÀ½.
912                //FreePMT(pmt);
913        }
914}
915
916
917
918#if 0 // remove old callback function
919
920BOOL _Dmc_UserDataCallback(TLVideoContext *context, UINT32 userParam)
921{
922        if (_Dmc_UserDataProc)
923                _Dmc_UserDataProc(context);
924        return FALSE;
925}
926
927
928/*
929 * _Dmc_ImportantVideoChangeEvent is called directly in response to a videoImportantChange event
930 * from the video driver task. We do most of the work by sending
931 * a decode event in a message queue which causes handleImportantVideoChange to be called in the
932 * lower priority video control task. This function needs to return TRUE only in outtput=input
933 * mode when we know that handleImportantVideoChange will change the format anyway. Otherwise
934 * it returns false meaning that the high-level video driver code should handle the format
935 * change for a fixed output format. Performing this check in both tasks avoides changing the
936 * format twice. We should not modify the current TL850VideoDisplay or timing from within the
937 * video driver task.
938 */
939BOOL _Dmc_ImportantVideoChangeCallback(TLVideoContext *context, UINT32 userParam)
940{
941        if (VideoContextIsAnalog(context))
942                return FALSE;           // Don't worry about analog contexts
943
944        // videoUserProc¿¡¼­ importantChange event°¡ ¼ö½ÅµÈ °æ¿ì ÀÌ ÇÔ¼ö°¡ ºÒ¸°´Ù.
945        //
946        // ¸®ÅϰªÀÇ ÀǹÌ: (bProcessed)
947        // TRUEÀ̸é event 󸮰¡ ³¡³µÀ¸¹Ç·Î driver¿¡¼­ ¾Æ¹« Àϵµ ÇÏÁö ¸»¶ó´Â ÀǹÌ.
948        //     application¿¡¼­ ´ëÀÀÀ» ÇϰڴÙ
949        // FALSE¸¦ ¸®ÅÏÇϸé driver°¡ ¾Ë¾Æ¼­ ´ëÀÀÇÑ´Ù.
950        //
951        // NaturalMode¸¦ Áö¿øÇÏÁö¸¸ ¿©·¯°¡Áö ¸®¼Ò½º ¹®Á¦ (pixmap planeµî)·Î
952        //   ¹Ù·Î ÇØ»óµµ¸¦ º¯°æÇϱ⠾î·Á¿î °æ¿ì°¡ ¸¹´Ù. (¿¹: OSD°¡ ¶°ÀÖ´Â °æ¿ì)
953        // ±×·¡¼­ ÀÏ´Ü driver·Î ÇÏ¿©±Ý ÃÖ¼ÒÇÑÀÇ ´ëÀÀ¸¸À» Çϵµ·Ï ÇÑ´Ù.
954        // ³ªÁß¿¡ ÀûÀýÇÑ »óȲÀÌ µÇ¸é (OSD°¡ exitµÇ´Â µî), application¿¡¼­ õõÈ÷
955        // Resolution change¸¦ ÇÏ¸é µÈ´Ù.
956        //
957       
958        _Dmc_SendDecodeEvent(evtVideoImportantChange, userParam);
959                                // jump to doDmc_HandleImportantVideoChange
960        return FALSE;
961}
962
963BOOL _Dmc_UserVideoChangeCallback(TLVideoContext *context, UINT32 userParam)
964{
965        // driver¿¡¼­ ¼öÇàÇÏ´Â Äڵ带 Àß º¸°í
966        // ¸¸¾à ±× ¹ÛÀÇ Ãß°¡ ÀÛ¾÷À» ÇÏ°í ½ÍÀ» °æ¿ì ¾Æ·¡¿Í °°ÀÌ low priority task·Î
967        // ÀÛ¾÷À» ¹Ì·ï ¼öÇàÇϵµ·Ï ÇÑ´Ù.
968        //
969        _Dmc_SendDecodeEvent(evtVideoUserChange, userParam);
970                                // jump to doDmc_HandleUserChange
971        return FALSE;
972}
973
974BOOL _Dmc_MajorVideoChangeCallback(TLVideoContext *context, UINT32 userParam)
975{
976        _Dmc_SendDecodeEvent(evtVideoMajorChange, userParam);
977                                // jump to doDmc_HandleMajorVideoChange
978        return FALSE;
979}
980
981// cafrii 060721 add
982BOOL _Dmc_VideoScrambledCallback(TLVideoContext *context, UINT32 userParam)
983{
984        _Dmc_SendDecodeEvent(evtVideoScrambled, userParam);
985                                // jump to doDmc_HandleVideoScrambled
986        return FALSE;
987}
988
989
990BOOL _Dmc_AudioInfoCallback(void *info, UINT32 userParam)
991{
992        // note that this event is called directly from driver task.
993        //   don't do any heavy job in this callback.
994       
995        doDmc_Notify(DMW_NOTIFY_AudioInfo, 0);
996
997        return FALSE;
998}
999
1000#else // remove old callback function
1001
1002BOOL _Dmc_VideoFreezeEndCallback(TLVideoContext *context, UINT32 userParam)
1003{
1004        _Dmc_SendDecodeEvent(evtFreezeVideoEnd, userParam);
1005                                // jump to doDmc_HandleFreezeVideoEnd
1006        return FALSE;
1007}
1008
1009BOOL _Dmc_ImportantVideoChangeCallback(TLVideoContext *context, UINT32 userParam)
1010{
1011        if (VideoContextIsAnalog(context))
1012                return FALSE;           // Don't worry about analog contexts
1013
1014        // videoUserProc¿¡¼­ importantChange event°¡ ¼ö½ÅµÈ °æ¿ì ÀÌ ÇÔ¼ö°¡ ºÒ¸°´Ù.
1015        //
1016        // ¸®ÅϰªÀÇ ÀǹÌ: (bProcessed)
1017        // TRUEÀ̸é event 󸮰¡ ³¡³µÀ¸¹Ç·Î driver¿¡¼­ ¾Æ¹« Àϵµ ÇÏÁö ¸»¶ó´Â ÀǹÌ.
1018        //     application¿¡¼­ ´ëÀÀÀ» ÇϰڴÙ
1019        // FALSE¸¦ ¸®ÅÏÇϸé driver°¡ ¾Ë¾Æ¼­ ´ëÀÀÇÑ´Ù.
1020        //
1021        // NaturalMode¸¦ Áö¿øÇÏÁö¸¸ ¿©·¯°¡Áö ¸®¼Ò½º ¹®Á¦ (pixmap planeµî)·Î
1022        //   ¹Ù·Î ÇØ»óµµ¸¦ º¯°æÇϱ⠾î·Á¿î °æ¿ì°¡ ¸¹´Ù. (¿¹: OSD°¡ ¶°ÀÖ´Â °æ¿ì)
1023        // ±×·¡¼­ ÀÏ´Ü driver·Î ÇÏ¿©±Ý ÃÖ¼ÒÇÑÀÇ ´ëÀÀ¸¸À» Çϵµ·Ï ÇÑ´Ù.
1024        // ³ªÁß¿¡ ÀûÀýÇÑ »óȲÀÌ µÇ¸é (OSD°¡ exitµÇ´Â µî), application¿¡¼­ õõÈ÷
1025        // Resolution change¸¦ ÇÏ¸é µÈ´Ù.
1026        //
1027       
1028        _Dmc_SendDecodeEvent(evtVideoImportantChange, userParam);
1029                                // jump to doDmc_HandleImportantVideoChange
1030        return FALSE;
1031}
1032
1033void _Dmc_CommonAVCallback(tDHL_AVCallbackType cb_type, UINT32 param)
1034{
1035        if (cb_type == eDHL_CB_VideoSeqHdr) {
1036                _Dmc_ImportantVideoChangeCallback((TLVideoContext)0, 0);
1037        }
1038        else if (cb_type == eDHL_CB_FirstVideoShow) {
1039                _Dmc_VideoFreezeEndCallback((TLVideoContext)0, 0);
1040        }
1041}
1042
1043#endif
1044
1045
1046#if COMMENT
1047_______________(){}
1048#endif
1049
1050
1051
1052//-----------------------------------------------------------------
1053// doDmc functions.
1054//
1055// These functions can be called only in dmc task.
1056//
1057
1058void doDmc_Notify(UINT32 event, UINT32 param)
1059{
1060        const char *name = Dmc_NotifyEventString(event);
1061               
1062        if (_Dmc_Notify) {
1063                dprint(3, "----> %s start.. (%x)\n", name, param);
1064                _Dmc_Notify(event, param);
1065        }
1066        else {
1067                dprint(3, " Notify '%s' (%d) not registerred. skip\n", name, event); // cafrii 040521 add event number for easy debugging
1068        }
1069}
1070
1071
1072
1073//----------------------------------------------------------------------
1074
1075
1076
1077//  doDmc_StartFinalPsiMonitor
1078//
1079//  digital channel tuningÀÌ ¸ðµÎ ³¡³ª°í ³ª¸é PSI ¸ð´ÏÅ͸¦ ½ÃÀÛÇÑ´Ù.
1080//
1081void doDmc_StartFinalPsiMonitor(BOOL bCancelPrevMonitors)
1082{
1083        DHL_RESULT err;
1084       
1085        ProgramAVInfo *av = Dmc_LockAVMutex();
1086
1087#if USE_EPG_MW_PSI_DOWNLOAD
1088        // ±âÁ¸ psi monitor´Â °­Á¦·Î Áß´Ü ÇÑ´Ù.
1089        if (av->pmtPsiCtl)
1090                DHL_PSI_StopMonitor(av->pmtPsiCtl);
1091        av->pmtPsiCtl = NULL;
1092        if (av->patPsiCtl)
1093                DHL_PSI_StopMonitor(av->patPsiCtl);
1094        av->patPsiCtl = NULL;
1095
1096#else // !USE_EPG_MW_PSI_DOWNLOAD
1097        //TLASSERT(av->active, "Video should be already started!");
1098       
1099        if (bCancelPrevMonitors) {
1100#if USE_CH_MW_ALL_PMT_DOWNLOAD
1101                if (av->pmtPsiCtl2) {
1102                        DHL_PSI_StopMonitor(av->pmtPsiCtl2);
1103                        av->pmtPsiCtl2 = (tDHL_PSI_ControlHandle)0;
1104                }
1105#endif
1106                if (av->pmtPsiCtl) {
1107                        DHL_PSI_StopMonitor(av->pmtPsiCtl);
1108                        av->pmtPsiCtl = (tDHL_PSI_ControlHandle)0;
1109                }
1110                if (av->patPsiCtl) {
1111                        DHL_PSI_StopMonitor(av->patPsiCtl);
1112                        av->patPsiCtl = (tDHL_PSI_ControlHandle)0;
1113                }
1114        }
1115
1116        if (gDmcTestNoPsiMonitor) {
1117                dprint(2, gDmcStringNoPsiMonitor);
1118        }
1119        else if (av->patPsiCtl) {
1120                dprint(2, "    Psi monitor already exist\n");
1121        }
1122        else {
1123                dprint(2, "    Start monitor PAT..\n");
1124
1125                err = MonitorPAT(Dmc_GetCurrentTsd(),
1126                                TRUE, // Ç×»ó current PAT¸¸ ¹Þ´Â´Ù!!
1127                                FALSE, // not eager
1128                                dmc_PatUpdateMode,
1129                                _Dmc_PatEventProc, 0,
1130                                &av->patPsiCtl);
1131       
1132                if (err) {
1133                        dprint(0, "!! MonitorPAT returned %s\n", ErrorString(err));
1134                }
1135        }
1136#endif // USE_EPG_MW_PSI_DOWNLOAD
1137
1138        Dmc_UnlockAVMutex();
1139}
1140
1141
1142static void doDmc_CancelMonitors()
1143{
1144        int i;
1145        ProgramAVInfo *av = Dmc_LockAVMutex();
1146
1147#if USE_CH_MW_ALL_PMT_DOWNLOAD
1148        if(av->pmtPsiCtl2) {
1149                DHL_PSI_StopMonitor(av->pmtPsiCtl2);
1150                av->pmtPsiCtl2 = (tDHL_PSI_ControlHandle)0;
1151        }
1152#endif
1153        if(av->pmtPsiCtl) {
1154                DHL_PSI_StopMonitor(av->pmtPsiCtl);
1155                av->pmtPsiCtl = (tDHL_PSI_ControlHandle)0;
1156        }
1157        if(av->patPsiCtl) {
1158                DHL_PSI_StopMonitor(av->patPsiCtl);
1159                av->patPsiCtl = (tDHL_PSI_ControlHandle)0;
1160        }
1161       
1162        if (av->pmt)
1163                FreePMT(av->pmt);
1164        av->pmt = NULL;
1165
1166#if USE_CH_MW_ALL_PMT_DOWNLOAD
1167        for (i=0; av->pat && av->pmtList && i<av->pat->numPrograms; i++)
1168                if (av->pmtList[i])
1169                        FreePMT(av->pmtList[i]);
1170        DHL_OS_Free((void **)&av->pmtList);
1171#endif 
1172        if (av->pat)
1173                FreePAT(av->pat);
1174        av->pat = NULL;
1175           
1176        Dmc_UnlockAVMutex();
1177}
1178
1179
1180
1181/*
1182        app callbackÀ» ÀÌ¿ëÇÏ¿©, app¿¡¼­ ¿øÇÏ´Â audio ½ºÆ®¸²À» ¼±ÅÃÇϵµ·Ï ÇÏ´Â ÇÔ¼ö.
1183        ±âº»ÀûÀ¸·Î MW ³»ºÎÀÇ DecidePidInfo ·çƾ¿¡¼­ ÀûÀýÇÑ pid¸¦ ¼±ÅÃÇÑ´Ù.
1184
1185        ±×·¯³ª MW ³»ºÎ ·ÎÁ÷Àº language code´Â °í·ÁÇÏÁö ¾ÊÀ¸¹Ç·Î,
1186        preferred language ±â´ÉÀÌ ÀÖ´Â Á¦Ç°ÀÇ app À̶ó¸é callbackÀ» ¹Ýµå½Ã ±¸ÇöÇØ¾ß ÇÑ´Ù.
1187*/
1188void doDmc_SelectAudioStream(MPEG_PMT *pmt, xvctChannelPtr_t vctc, 
1189                        UINT32 *pAudioPID, tDHL_AudioCodingType *pAudioType)
1190{
1191        // Notification callbackÀ» ÀÌ¿ëÇÏ¿© application¿¡¼­ ¾î¶² audio¸¦ ¿øÇÏ´ÂÁö ¾Ë¾Æ³½´Ù.
1192        //
1193        AudioPidSelectParam apsp;
1194        UINT32 audioPID;
1195        tDHL_AudioCodingType audioType;
1196       
1197        apsp.pmt = pmt;
1198        apsp.vctChannel = vctc; 
1199        // ¾Æ·¡ µÎ °ª¿¡´Â callback ÀÌ ±¸ÇöµÇ¾ú´ÂÁö¸¦ üũÇϱâ À§ÇÑ ÃʱⰪÀ» ³Ö¾îµÐ´Ù.
1200        apsp.returnAudioPid = 0;
1201        apsp.returnAudioType = eDHL_AUDIO_TYPE_UNKNOWN;
1202
1203        doDmc_Notify(DMW_NOTIFY_SelectAudio, (UINT32) &apsp);
1204       
1205        if (apsp.returnAudioPid || apsp.returnAudioType) 
1206        {
1207                if (apsp.returnAudioPid != 0)
1208                        audioPID = apsp.returnAudioPid;
1209                if (apsp.returnAudioType != eDHL_AUDIO_TYPE_UNKNOWN)
1210                        audioType = apsp.returnAudioType;
1211                       
1212                dprint(2, "\t user select audio PID %d, type %d\n", audioPID, audioType);
1213               
1214                if (pAudioPID) *pAudioPID = audioPID;
1215                if (pAudioType) *pAudioType = audioType;
1216        }
1217        else {
1218                /*
1219                        pAudioPID ¿Í pAudioType¿¡´Â ÀÌ¹Ì MW ³»ºÎ¿¡¼­ ¼±ÅÃÇÑ °ªÀÌ µé¾î ÀÖÀ¸¹Ç·Î
1220                        °ªÀ» º¯°æÇÏ¸é ¾ÈµÈ´Ù.
1221                */
1222        }
1223}
1224
1225
1226/*
1227        app callbackÀ» ÀÌ¿ëÇÏ¿©, app¿¡¼­ ¿øÇÏ´Â video ½ºÆ®¸²À» ¼±ÅÃÇϵµ·Ï ÇÏ´Â ÇÔ¼ö.
1228        ±âº»ÀûÀ¸·Î MW ³»ºÎÀÇ DecidePidInfo ·çƾ¿¡¼­ ÀûÀýÇÑ pid¸¦ ¼±ÅÃÇÑ´Ù.
1229
1230        Ưº°ÇÑ ·ÎÁ÷ÀÌ ÇÊ¿äÇÏÁö ¾Ê´Â ÇÑ, callbackÀ» ±¸ÇöÇÒ ÇÊ¿ä ±îÁö´Â ¾ø´Ù.
1231*/
1232void doDmc_SelectVideoStream(MPEG_PMT *pmt, xvctChannelPtr_t vctc,
1233                        UINT32 *pVideoPID, tDHL_VideoCodingType *pVideoType)
1234{
1235        // Notification callbackÀ» ÀÌ¿ëÇÏ¿© application¿¡¼­ ¾î¶² video¸¦ ¿øÇÏ´ÂÁö ¾Ë¾Æ³½´Ù.
1236        //
1237        VideoPidSelectParam vpsp;
1238        UINT32 videoPID;
1239        tDHL_VideoCodingType videoType;
1240       
1241        vpsp.pmt = pmt;
1242        vpsp.vctChannel = vctc; 
1243        // ¾Æ·¡ µÎ °ª¿¡´Â callback ÀÌ ±¸ÇöµÇ¾ú´ÂÁö¸¦ üũÇϱâ À§ÇÑ ÃʱⰪÀ» ³Ö¾îµÐ´Ù.
1244        vpsp.returnVideoPid = 0;
1245        vpsp.returnVideoType = eDHL_VIDEO_TYPE_UNKNOWN;
1246
1247        doDmc_Notify(DMW_NOTIFY_SelectVideo, (UINT32) &vpsp);
1248       
1249        if (vpsp.returnVideoPid || vpsp.returnVideoType != eDHL_VIDEO_TYPE_UNKNOWN) 
1250        {
1251                if (vpsp.returnVideoPid != 0)
1252                        videoPID = vpsp.returnVideoPid;
1253                if (vpsp.returnVideoType != eDHL_VIDEO_TYPE_UNKNOWN)
1254                        videoType = vpsp.returnVideoType;
1255                       
1256                dprint(2, "\t user select video PID %d, type %d\n", videoPID, videoType);
1257               
1258                if (pVideoPID) *pVideoPID = videoPID;
1259                if (pVideoType) *pVideoType = videoType;
1260        }
1261        else if(pmt) {
1262                //neverdai 101019 video streamÀÇ °æ¿ì, pid¿Í stream typeÀ» pmt¿¡¼­ ã¾Æ ¼³Á¤ÇØÁÜ.
1263                #define StreamTypeToVideoType(t) ( \
1264                                (t) == StreamType_MPEG2Video ? eDHL_VIDEO_TYPE_MPEG2 : \
1265                                (t) == StreamType_DC2Video   ? eDHL_VIDEO_TYPE_MPEG2 : \
1266                                (t) == StreamType_MPEG1Video ? eDHL_VIDEO_TYPE_MPEG1 : \
1267                                (t) == StreamType_H264       ? eDHL_VIDEO_TYPE_H264 : \
1268                                        eDHL_VIDEO_TYPE_UNKNOWN )
1269               
1270                int i, num_video, video_idx;
1271               
1272                for(i=0, num_video=0; i<pmt->numStreams; i++) {
1273                        if(StreamTypeToVideoType(pmt->streams[i].stream_type)!=eDHL_VIDEO_TYPE_UNKNOWN) {
1274                                num_video++;
1275                                videoPID=pmt->streams[i].elementary_PID;
1276                                videoType=StreamTypeToVideoType(pmt->streams[i].stream_type);
1277                        }
1278                }
1279                       
1280                if(num_video==1) {
1281                        if (pVideoPID) *pVideoPID = videoPID;
1282                        if (pVideoType) *pVideoType = videoType;
1283                }
1284        }
1285        else {
1286                /*
1287                        pVideoPID ¿Í pVideoType¿¡´Â ÀÌ¹Ì MW ³»ºÎ¿¡¼­ ¼±ÅÃÇÑ °ªÀÌ µé¾î ÀÖÀ¸¹Ç·Î
1288                        °ªÀ» º¯°æÇÏ¸é ¾ÈµÈ´Ù.
1289                */
1290        }
1291}
1292
1293
1294
1295/*
1296        running time Áß¿¡ importantchange (seqhdr ¼ö½Å) ¹ß»ý½Ã È£Ãâ.
1297        synchronous start ÀÎ °æ¿ì¿¡´Â video start ½Ã¿¡µµ È£Ãâ.
1298
1299
1300*/
1301BOOL doDmc_CheckIfFormatChanged(void)
1302{
1303        DHL_RESULT dhlResult;
1304        BOOL bFormatChanged = FALSE;
1305        char buf1[80], buf2[80];
1306       
1307        tDHL_VideoSeqHdr seqtmp, *seq1, *seq2 = &seqtmp;
1308
1309        ProgramAVInfo *av = Dmc_LockAVMutex();   //-------
1310
1311        // find new video format. if analog, seq set to NULL.
1312        if (!DHL_AV_IsDigitalContext())
1313                seq2 = NULL;
1314        else {
1315                // ¿©±â¿¡¼­´Â Àý´ë ¿¡·¯°¡ ¹ß»ýÇÏ¸é ¾ÈµÈ´Ù.
1316                dhlResult = DHL_AV_VideoSeqInfo(0, seq2);
1317                if (dhlResult) {
1318                        dprint(0, "!! %s: get seqhdr err\n", __func__);
1319                        seq2 = NULL;
1320                }
1321        }
1322
1323        // previous old video format
1324        seq1 = av->seq_hdr_valid ? &av->seq_hdr : NULL;
1325
1326        if (seq1 && seq2 && seq1->generationNumber == seq2->generationNumber) {
1327                dprint(2, "same seq_hdr number %u\n", seq1->generationNumber);
1328                goto label_end;
1329        }
1330       
1331        // make description string.
1332        // cafrii 070725 fix, ÀϺΠplatform¿¡¼­ floatÇü print ºÒ°¡´ÉÇÏ¿©
1333        //   interger type Ãâ·Â¸¸ »ç¿ëÇϵµ·Ï ¼öÁ¤.
1334        if (seq1)
1335                sprintf(buf1, "(%d: %4dx%4d %c %2d.%02dHz %s)",
1336                        Dmc_WhichATSCFormat(seq1),
1337                        seq1->horizontal_size, seq1->vertical_size, 
1338                        seq1->progressive_sequence ? 'p' : 'i', 
1339                        (int)(seq1->frame_rate), (int)(seq1->frame_rate*100) % 100,
1340                        DHL_AV_IsWideoFormat(seq1) ? "wide" : "narrow");
1341        else
1342                strcpy(buf1, "(00: Analog)");
1343
1344        if (seq2)
1345                sprintf(buf2, "(%d: %4dx%4d %c %2d.%02dHz %s)",
1346                        Dmc_WhichATSCFormat(seq2),
1347                        seq2->horizontal_size, seq2->vertical_size, 
1348                        seq2->progressive_sequence ? 'p' : 'i', 
1349                        (int)(seq2->frame_rate), (int)(seq2->frame_rate*100) % 100,
1350                        DHL_AV_IsWideoFormat(seq2) ? "wide" : "narrow");
1351        else
1352                strcpy(buf2, "(00: Analog)");
1353
1354        dprint(2, "\tsource %s\n\t  --->  %s\n", buf1, buf2);
1355
1356        if (seq1)
1357        {
1358                if (seq2) {   // digital --> digital
1359                        bFormatChanged = Dmc_CheckIfFormatChanged(seq2, seq1); // new, old
1360                        memcpy(&av->seq_hdr, seq2, sizeof(tDHL_VideoSeqHdr));
1361                        av->seq_hdr_valid = TRUE;
1362                }
1363                else {
1364                        bFormatChanged = TRUE;    // digital --> analog
1365                        av->seq_hdr_valid = FALSE;
1366                }
1367        }
1368        else // seq1 == NULL
1369        {
1370                if (seq2) {    // analog --> digital
1371                        bFormatChanged = TRUE;
1372                        memcpy(&av->seq_hdr, seq2, sizeof(tDHL_VideoSeqHdr));
1373                        av->seq_hdr_valid = TRUE;
1374                }
1375                else {
1376                        bFormatChanged = FALSE;  // analog --> analog
1377                        av->seq_hdr_valid = FALSE;
1378                }
1379        }
1380
1381label_end:
1382        Dmc_UnlockAVMutex(); //-------
1383       
1384        return bFormatChanged;
1385}
1386       
1387
1388// doDmc_ProcessScreenAdjustment
1389//   tuning ´Ü°è¿¡¼­, Àû¿ëÇÒ adjustment ¹æ¹ýÀ» callbackÀ¸·Î queryÇØ¼­ Àû¿ëÇÑ´Ù.
1390//
1391// user¿¡°Ô ¾Ë·ÁÁÙ ³»¿ë
1392// input:
1393//   ÇöÀç display ratio (wide/narrow)
1394//   ÇöÀç source format ratio (wide/narrow)
1395
1396// output:
1397//   tDHL_DispARC
1398//   force widebar
1399//   winRect
1400//
1401void doDmc_ProcessScreenAdjustment(void)
1402{
1403        // video start ÇÒ ¶§ display start Çϱâ Àü¿¡ ºÒ¸°´Ù.
1404
1405        ScreenAdjustmentParam sap;
1406        DHL_RESULT dhr;
1407
1408        ProgramAVInfo *av = Dmc_LockAVMutex();
1409
1410        memset(&sap, 0, sizeof(sap));
1411
1412        // input
1413        sap.bSourceWide = DHL_AV_IsWideoFormat(&av->seq_hdr) ? TRUE : FALSE;
1414        sap.bDisplayWide = TRUE; 
1415                // ÀÌ display ratio´Â ¿ø·¡ Dmc_ChangeDisplay api ÀÎÀÚ¸¦ ±â¾ïÇØ µÎ¾î¼­ Àü´ÞÇØ ÁÖ´Â °ªÀε¥,
1416                // ÇöÀç MW ±¸Á¶¿¡¼­´Â º°µµ·Î ±â¾ïÀ» ¾ÈÇØµÎ°í ÀÖ´Ù.
1417                // MW Á¤º¸ º¸´Ù app Á¤º¸°¡ ´õ ½Å·ÚÇÒ ¼ö ÀÖÀ¸¹Ç·Î app ¿¡¼­´Â ÀÌ Á¤º¸¸¦ ¹«½ÃÇϰí,
1418                // app º¯¼ö¸¦ Âü°íÇÏ´Â °ÍÀÌ ÁÁ°Ú´Ù.
1419       
1420        // output
1421        // fill with special indicator value.
1422        sap.adjustment_hd = eDHL_ARC_UNKNOWN;  // this value should not be used.
1423        SETRECT(&sap.rect, 0, 0, 0, 0);
1424
1425        Dmc_UnlockAVMutex();
1426       
1427        doDmc_Notify(DMC_NOTIFY_ScreenAdjustment, (UINT32)&sap);
1428
1429        if (sap.bKeepCurrent) {
1430                dprint(2, "keep current adj setting\n");
1431                return;
1432        }
1433               
1434       
1435        if (sap.adjustment_hd == (tDHL_DispARC)eDHL_ARC_UNKNOWN) {
1436                dprint(0, "!! screen adjust noti not impl. use default\n");
1437                sap.adjustment_hd = eDHL_ARC_FULLSCREEN;
1438                sap.adjustment_sd = eDHL_ARC_FULLSCREEN;
1439        }
1440
1441        dhr = DHL_AV_VideoSetARC(sap.adjustment_hd, sap.adjustment_sd);
1442        if (dhr) {
1443                dprint(0, "!! set arc err 0x%x. retry..\n", dhr);
1444                DHL_OS_Delay(100);
1445                DHL_AV_VideoSetARC(sap.adjustment_hd, sap.adjustment_sd);
1446        }
1447}
1448
1449
1450#if USE_CH_MW_ALL_PMT_DOWNLOAD
1451/*
1452        ÇöÀç ½ÃûÁßÀÌ ¾Æ´Ñ ´Ù¸¥ pmtµéµµ ´Ù ´Ù¿î·Îµå ÇÑ´Ù.
1453*/
1454void doDmc_StartAllPmtMonitor(ProgramAVInfo *av)
1455{
1456        DHL_RESULT err;
1457        int program_index;
1458        UINT16 pmt_pid, program_number;
1459        int i;
1460
1461        if (!av->pat)
1462                goto label_exit;
1463       
1464        if (!av->pmtList) 
1465                goto label_exit;
1466
1467        // ÇϳªÀÇ filter·Î ¿©·¯ pmt¸¦ ÇѲ¨¹ø¿¡ ´Ù ¹Þ´Â °ÍÀÌ ¾Æ´Ï¶ó
1468        // pmt¸¦ Çϳª¾¿ ¼øÂ÷ÀûÀ¸·Î ¹Þ´Â ¹æ¹ýÀ» »ç¿ëÇÑ´Ù.
1469        // »õ MW¿¡¼­´Â ÀÌ·± ºÎºÐÀº °³¼±ÀÌ °¡´ÉÇÔ..
1470        if (av->pmtPsiCtl2) {
1471                dprint(2, "  stop allpmt psictl2\n");
1472                DHL_PSI_StopMonitor(av->pmtPsiCtl2);
1473                av->pmtPsiCtl2 = (tDHL_PSI_ControlHandle)0;
1474        }
1475       
1476        // ´Ù¸¥ ¼­ºê ä³Î Áß¿¡¼­ ¾ÆÁ÷ ¹Þ¾ÆÁöÁö ¾ÊÀº program ¼±ÅÃ.
1477        program_index = -1;
1478        for (i=0; av->pmtList && i<av->pat->numPrograms; i++) {
1479                if (av->pat->programs[i].program_number == av->program_number) 
1480                        continue; // ÀÌ ÇÁ·Î±×·¥Àº 'ÇöÀç' ÇÁ·Î±×·¥À̹ǷΠskip..
1481
1482                if (av->pmtList[i])
1483                        continue; // ÀÌ¹Ì ¹Þ¾ÆÁ® ÀÖ´Ù¸é skip..
1484                program_index = i;
1485                pmt_pid        = av->pat->programs[i].program_map_PID;
1486                program_number = av->pat->programs[i].program_number;
1487                break;
1488        }
1489        if (program_index < 0) { // ÀÌ¹Ì ´Ù ¹Þ¾ÆÁø °æ¿ì¶ó¸é ±×³É Á¾·á.
1490                // cafrii 110331 add param
1491                AllPsiRxNotifyInfo param;
1492                memset(&param, 0, sizeof(param));
1493                param.av = av;
1494                dprint(2, "  all other %d pmts are downloaded.\n", av->pat->numPrograms-1);
1495                doDmc_Notify(DMC_NOTIFY_AllPsiReceived, (UINT32)&param);
1496                goto label_exit;
1497        }
1498       
1499        // ´Ù¿î·Îµå ½ÃÀÛ..
1500        dprint(2, "  monitor other pmt[%d] pid %d, #%d..\n", 
1501                                        program_index, pmt_pid, program_number);
1502        err = MonitorPMT(Dmc_GetCurrentTsd(),
1503                                         pmt_pid, program_number, TRUE, ePSIUPDATE_ONESHOT,
1504                                         _Dmc_PmtEventProc, 0, &av->pmtPsiCtl2);
1505        if (err) {
1506                dprint(0, "!! MonitorPMT returned %s\n", ErrorString(err));
1507        }
1508        goto label_exit;
1509       
1510
1511label_exit:
1512        return;
1513}
1514
1515#endif // USE_CH_MW_ALL_PMT_DOWNLOAD
1516
1517
1518void doDmc_AudioTempMute(BOOL bMute)
1519{
1520        // ´Ù¸¥ MW µî¿¡¼­ Decoder mute´Â »ç¿ëÇÏÁö ¾Ê°í À־
1521        // À̰ÍÀ» temp mute·Î »ç¿ëÇÔ.
1522        DHL_AV_AudioMuteControl(eDHL_AUDIO_MUTE_DECODER, bMute);
1523}
1524
1525void doDmc_AudioTempMuteLimitTimerProc(UINT32 nIDTimer, UINT32 param)
1526{
1527        dprint(2, "\t audio temp unmute by timer limit\n");
1528        doDmc_AudioTempMute(FALSE);
1529}
1530
1531
1532
1533
1534#if COMMENT
1535_______EventHandler________(){}
1536#endif
1537
1538
1539
1540
1541
1542// doDmc_HandlePatChange
1543//
1544// PAT monitorÀÇ °á°ú·Î ºÒ¸®´Â event procedure.
1545// PAT Change EventÀÇ DMC level Deferred Procedure
1546// Dmc task ¿¡¼­ È£ÃâµÈ´Ù.
1547//
1548void doDmc_HandlePatChange(DmcMessage *pmsg)
1549{
1550        DHL_RESULT err;
1551        int i;
1552        int program_index = -1;
1553        BOOL bIgnoreNewPat = FALSE; 
1554       
1555        UINT16 pmt_pid;
1556        UINT16 program_number;
1557       
1558        MPEG_PAT *pat = (MPEG_PAT *)pmsg->param;
1559       
1560        ProgramAVInfo *av = Dmc_LockAVMutex();
1561       
1562        if (g_Trace_bDmcPsiEvent)
1563                dprint(1, "evtPatChange:::: cid %d\n", pmsg->cancelId);
1564
1565#if 1 // PSI_WO_CHVIEW
1566        if (av->active == 0) {
1567                dprint(2, "  psi w/o chview\n");
1568        }
1569#else
1570        if (av->active == 0 || av->analog) {
1571                dprint(0, "!! pat is received in invalid state\n");
1572                goto label_exit;
1573        }
1574#endif
1575
1576        if (pat == NULL || pat->numPrograms == 0 || pat->programs == NULL) {
1577                dprint(0, "!! invalid new PAT in in HandlePatChange\n");
1578                goto label_exit;
1579        }
1580       
1581        // StopVideo¸¦ ÇÏ´Â ±× ¼ø°£¿¡ MessageQueue¿¡ ÀÖ´Â PAT change event°¡ ³²¾Æ ÀÖ´Ù°¡
1582        // ³ªÁß¿¡ ÀÌ handler¿¡¼­ ´Ù½Ã video°¡ restartµÇ´Â ¹®Á¦°¡ ÀÖÀ» ¼ö ÀÖ´Ù.
1583        // ÀÌ ¹®Á¦´Â StopVideo¸¦ Çϸ鼭 Queue¿¡ ÀÖ´Â ¸ðµç event msg¸¦ »èÁ¦ÇÏ´Â °ÍÀ¸·Î ÇØ°áÇÑ´Ù.
1584        //
1585        // ±×·¡µµ Ȥ½Ã ¿À·¡µÈ event msg°¡ ´Ê°Ô ¿Ã °æ¿ì¸¦ ´ëºñÇØ¼­ psiControlÀÌ ÀÌ¹Ì »èÁ¦µÈ °æ¿ì¶ó¸é
1586        // ÀÌ À̺¥Æ®¸¦ ¹«½ÃÇÑ´Ù.
1587        //
1588        if (av->patPsiCtl == 0) {
1589                dprint(0, "!! patPsiCtl is NULL! it is already stopped context\n");
1590                goto label_exit;
1591        }
1592       
1593        // Pat change event°¡ ³Ê¹« ÀÚÁÖ ºÒ¸®´Â °æ¿ì
1594        // ±× ó¸® ¼Óµµ°¡ »õ patÀÇ ¼ö½Å ºóµµ¸¦ µû¶ó°¡Áö ¸øÇϸé
1595        // Queue¿¡ ½×¿© ÀÖÀ» ¼öµµ ÀÖ´Ù.
1596        // Queue¿¡ PAT change event°¡ ÀÌ¹Ì ÀÖÀ¸¸é À̹ø event´Â ¹«½ÃÇØµµ µÈ´Ù.
1597        //
1598        if (doDmc_CheckMsgExist(evtPatChange)) {
1599                dprint(2, "!! Future PAT Change event detected. ignore this..\n");
1600                goto label_exit;
1601        }
1602       
1603        // current program number of decoded program..
1604        program_number = av->program_number;
1605       
1606        if (g_Trace_bDmcPsiEvent) {
1607                dprint(2, "PAT change event! TSID %d, version %d, num_program %d\n",
1608                        pat->transport_stream_id,
1609                        pat->version_number, pat->numPrograms);
1610        }
1611       
1612        if (1) {
1613                PSIChangeNotifyInfo pcni;
1614       
1615                // Notify to user first.
1616                memset(&pcni, 0, sizeof(pcni));
1617       
1618                pcni.pmtchanged = FALSE; // This is PAT.
1619                pcni.pat = pat;
1620                //pcni.ignore = FALSE;  // This is [out] parameter. FALSE by default
1621                pcni.program_index = -1;
1622
1623                // cafrii 060804 add two more parameters
1624                pcni.userParam = av->userParam;
1625                pcni.av = av;
1626               
1627                doDmc_Notify(DMC_NOTIFY_PATChanged, (UINT32)&pcni);
1628       
1629                program_index = pcni.program_index;
1630        }
1631       
1632        // ¾Æ·¡ Á¶°ÇÀ̸é ÀÌ »õ·Î ¹ÞÀº pat¸¦ ó¸®ÇÏÁö ¾Ê´Â´Ù.
1633        //
1634        // 1. option¿¡¼­ equiv pat¸¦ ¹«½ÃÇ϶ó°í µÇ¾î ÀÖ°í,
1635        // 2. °Ë»ç °á°ú µ¿ÀÏÇÑ pat·Î °á°ú°¡ ³ª¿ÔÀ¸¸ç,
1636        // 3. pmt monitor°¡ Á¸ÀçÇϸé (ÀÌ°Ô Á¤¸»·Î µ¿ÀÏÇÑ °ÍÀÎÁö´Â È®ÀÎ ºÒ°¡)
1637        //
1638        if (dmc_bIgnoreEquivPat && 
1639                Dmc_CheckIfSamePat(av->pat, pat) &&
1640                av->pmtPsiCtl)  // cafrii 060707 bugfix!!   <-- av->pmtPsiCtl == 0
1641        {
1642                bIgnoreNewPat = TRUE;
1643        }
1644       
1645        // Note:
1646        // PMT Monitor°¡ ¾ÆÁ÷ ±âµ¿µÇÁö ¾Ê¾Ò´Ù¸é ¾î¶°ÇÑ °æ¿ì¶óµµ Ignore¸¦ ÇÏ¸é ¾ÈµÈ´Ù.
1647        // ¼³·É NewPat¸¦ ¹«½ÃÇ϶ó´Â °á°ú°¡ ³ª¿Ô´õ¶óµµ
1648        // Pmt Monitor°¡ ¾ÆÁ÷ ½ÃÀÛÇÏÁö ¾ÊÀº »óŶó¸é Monitor¸¦ ½ÃÀÛÇØ¾ß ÇÑ´Ù.
1649        //
1650
1651        // todo..
1652        // is pmtPsiCtl consistent with one of pat's entry?
1653        // PSIControl: av->pmtPsiCtl->psiFilter->entries[0..2] ¸¦ Á÷Á¢ Á¶»çÇØ¾ß ÇÔ..
1654        // -> ±×Á¤µµ±îÁö´Â ÇÊ¿ä ¾øÀ» µí..
1655
1656        if (bIgnoreNewPat) {
1657                if (g_Trace_bDmcPsiEvent)
1658                        dprint(2, "!! PAT is ignored. similar PAT is already active..\n");
1659                //FreePAT(pat); // ¾Æ·¡¿¡¼­ °°ÀÌ Ã³¸®ÇÔ.
1660                goto label_exit;
1661        }
1662       
1663        doDmc_UpdatePsiInfo(pat, NULL);
1664        pat = NULL;
1665       
1666        //--------------------
1667        // new pat udpated. now processing..
1668       
1669        // decide program index..
1670       
1671        if (program_index < 0 || 
1672                program_index >= av->pat->numPrograms) 
1673        {
1674                // »ç¿ëÀÚ°¡ program_index¸¦ ¼³Á¤ÇÏÁö ¾Ê¾Ò°Å³ª
1675                // ÁöÁ¤ÇÑ program_index°¡ invalid ÇÑ °æ¿ìÀÌ´Ù. 
1676                // °¡Àå Àû´çÇÑ program À» ¼±ÅÃÇØ¾ß ÇÑ´Ù.
1677                //
1678                // search current program in PAT  using current program_number.
1679                // »õ·Î¿î PAT¿¡¼­ Áö±Ý±îÁö »ç¿ëÇØ¿Ô´ø ÇÁ·Î±×·¥ÀÇ program number¸¦ ã´Â´Ù.
1680                //
1681                dprint(2, "\tsearch program number %d\n", program_number);
1682               
1683                for (i=0; i<av->pat->numPrograms; i++) {
1684                        if (av->pat->programs[i].program_number == program_number)
1685                                break;
1686                }
1687               
1688                if (i >= av->pat->numPrograms) 
1689                {
1690                        dprint(0, "\n!!!! program number %d not found in PAT.\n", program_number);
1691
1692        #if !DMC_STOP_WHEN_PROGRAM_DISAPPEAR
1693                #if 0
1694                        dprint(0, "!!!! re-tune first program..\n");
1695                        program_index = 0;  // try using first program..
1696                       
1697                #else   //neverdai ÀÓ½Ã..ÃÖ¼Ò program_number¸¦ ¼±ÅÃÇÑ´Ù.
1698                        {
1699                                int j,numMin,minIdx;
1700                                for(j=0, numMin=0xffff,minIdx=0; j<av->pat->numPrograms; j++){
1701                                        if(numMin>av->pat->programs[j].program_number) {
1702                                                numMin=av->pat->programs[j].program_number;
1703                                                minIdx=j;
1704                                        }
1705                                }
1706                                program_index=minIdx;
1707                        }
1708                #endif
1709        #else
1710                        dprint(0, "ignore pat.. do nothing\n");
1711                        program_index = -1;
1712                        // just keep current state.
1713                        // probably video will be freezed if pid is not matched.
1714                        // follow your customers optinion..
1715        #endif // DMC_STOP_WHEN_PROGRAM_DISAPPEAR
1716               
1717                }
1718                else {
1719                        // found matched program.
1720                        //
1721                        program_index = i;
1722                }
1723        }
1724       
1725        if (program_index < 0 || 
1726                program_index >= av->pat->numPrograms) 
1727        {
1728                dprint(0, "!! program index %d invalid. should be [%d~%d]\n", 
1729                                                program_index, 0, av->pat->numPrograms-1);
1730
1731        #if DMC_STOP_WHEN_PROGRAM_DISAPPEAR
1732                goto label_fail;
1733        #else
1734                goto label_exit;
1735        #endif
1736               
1737        }
1738       
1739        pmt_pid        = av->pat->programs[program_index].program_map_PID;
1740        program_number = av->pat->programs[program_index].program_number;
1741
1742        if (pmt_pid <= 0 || pmt_pid >= 0x1FFF)
1743        {
1744                dprint(0, "!! PMT pid 0x%x invalid\n", pmt_pid);
1745                goto label_exit;
1746        }
1747       
1748
1749        // PMT monitor¸¸ »èÁ¦ÇÑ´Ù.
1750        // ±âÁ¸ PMT ¸®¼Ò½º´Â »èÁ¦ÇÏÁö ¾Êµµ·Ï ÇÑ´Ù.
1751        // ¹Ø¿¡¼­ PmtMonitor¸¦ ½ÃÀÛÇϹǷΠ¾ó¸¶ ÈÄ¿¡ »õ PMT°¡ ¼ö½ÅµÇ¸é ±×¶§ ±³Ã¼ÇÑ´Ù.
1752        //
1753        if (av->pmtPsiCtl)
1754                DHL_PSI_StopMonitor(av->pmtPsiCtl);
1755        av->pmtPsiCtl = (tDHL_PSI_ControlHandle)0;
1756
1757        dprint(2, "\tmonitor PMT (pid %d) of program idx %d, prognum %d\n", 
1758                         pmt_pid,
1759                         program_index, 
1760                         program_number);
1761                       
1762        err = MonitorPMT(Dmc_GetCurrentTsd(),
1763                                         pmt_pid,
1764                                         program_number,
1765                                         TRUE, // current
1766                                         dmc_PmtUpdateMode,
1767                                         _Dmc_PmtEventProc,
1768                                         0,   // userParam
1769                                         &av->pmtPsiCtl);
1770        if (err) {
1771                dprint(0, "!! MonitorPMT returned %s\n", ErrorString(err));
1772        }
1773
1774        // ¸ÕÀú ÇöÀç ½Ãû ÁßÀÎ ÇÁ·Î±×·¥ÀÇ pmt ºÎÅÍ ¹ÞÀº ÈÄ¿¡ ½ÃÀÛÇÏ´Â °ÍÀÌ ÁÁ°ÚÀ½.
1775#if 0 // USE_CH_MW_ALL_PMT_DOWNLOAD
1776        //doDmc_StartAllPmtMonitor(av);
1777#endif
1778        goto label_exit;
1779
1780#if DMC_STOP_WHEN_PROGRAM_DISAPPEAR
1781
1782label_fail:
1783        // ½ÇÇà ÁßÀÎ AV¸¦ ÁßÁö½ÃŲ´Ù.
1784
1785        dprint(2, "!! stop current AV..\n");
1786        doDmc_Stop();
1787
1788        // ÇÊ¿äÇϸé application¿¡ ÀÌ »óȲÀ» Åëº¸ÇØ ÁÙ Çʿ䰡 ÀÖ´Ù.
1789        doDmc_Notify(DMC_NOTIFY_PATChangeError, 0);
1790
1791#endif
1792
1793       
1794label_exit:
1795
1796        if (pat) 
1797        {
1798#if DMC_CHECK_HEAP_SIZE
1799                UINT32 heap_before = DHL_GetFreeHeapSize(0);
1800                FreePAT(pat);
1801                dprint(2, "free pat 0x%x.. heap %u->%u\n", 
1802                        pat, heap_before, DHL_GetFreeHeapSize(0));
1803#else
1804                FreePAT(pat);
1805                dprint(2, "free pat 0x%x..\n", pat);
1806#endif
1807        }
1808        Dmc_UnlockAVMutex();
1809       
1810}
1811
1812
1813// doDmc_HandlePmtChange
1814//
1815// PMT Change EventÀÇ DMC level Deferred Procedure
1816// Dmc task ¿¡¼­ È£ÃâµÈ´Ù.
1817//
1818#if USE_CH_MW_ALL_PMT_DOWNLOAD
1819// ÇöÀç ½Ãû ÁßÀΠä³ÎÀÇ pmt À̵ç, ½ÃûÇÏÁö ¾Ê´Â pmt ÀÌµç °£¿¡ ¸ðµÎ ÀÌ
1820// callback ¿¡¼­ 󸮵ȴÙ. µû¶ó¼­ ÀÌ µÑÀ» Àß ±¸ºÐÇØ¾ß ÇÔ.
1821#endif
1822void doDmc_HandlePmtChange(DmcMessage *pmsg)
1823{
1824        UINT32 videoPID = 0, audioPID = 0, pcrPID = 0;
1825        tDHL_AudioCodingType audioType = eDHL_AUDIO_TYPE_UNKNOWN;
1826        tDHL_VideoCodingType videoType = eDHL_VIDEO_TYPE_UNKNOWN;
1827        BOOL bVideoOutputExist;
1828        DHL_RESULT err;
1829        STATUS status;
1830       
1831        PidInfo psiPid;
1832        MPEG_PMT *pmt = (MPEG_PMT *)pmsg->param;
1833        UINT16 pmt_pid, program_number;
1834
1835        ProgramAVInfo prev_av, *av = Dmc_LockAVMutex();
1836
1837        if (g_Trace_bDmcPsiEvent)
1838                dprint(1, "evtPmtChange:::: cid %d\n", pmsg->cancelId);
1839
1840        if (av->pmtPsiCtl == 0) {
1841                // VideoStopÀ» ÇÏ°í ³ª¸é doDmc_DeleteAllEventMsg ¸¦ ºÒ·¯¼­ ÀÚµ¿À¸·Î
1842                // ¸ðµç PsiCtlÀ» cancel ½Ã۰í Àֱ⠶§¹®¿¡ ³í¸®ÀûÀ¸·Î ÀÌ·±°Ô ¹ß»ýÇÏ¸é ¾ÈµÈ´Ù.
1843                //
1844                dprint(0, "!! pmtPsiCtl is NULL! it is already stopped context\n");
1845                goto label_exit;
1846        }
1847
1848        if (doDmc_CheckMsgExist(evtPmtChange)) {
1849                dprint(2, "!! Future PMT Change event detected. ignore this..\n");
1850                goto label_exit;
1851        }
1852
1853        // check integrity
1854        //
1855        if (av->pat == NULL || av->pat->numPrograms == 0 || av->pat->programs == NULL)
1856                goto label_exit;
1857               
1858        if (pmt == NULL) {
1859                dprint(0, "!! Invalid pmt\n");
1860                goto label_exit;
1861        }
1862
1863#if 1 // PSI_WO_CHVIEW
1864        if (av->active == 0) {
1865                dprint(2, "  psi w/o chview\n");
1866        }
1867#else
1868        if (av->active == 0 || av->analog) {
1869                dprint(0, "!! pmt is received in invalid state\n");
1870                goto label_exit;
1871        }
1872#endif
1873
1874#if USE_CH_MW_ALL_PMT_DOWNLOAD
1875        if (pmt->program_number != av->program_number) 
1876        {
1877                // ÇöÀç ½ÃûÁßÀÌ ¾Æ´Ñ ¼­ºêä³ÎÀÇ pmtÀÎ °æ¿ìÀÌ´Ù.
1878                int i;
1879                dprint(2, "non-viewing program pmt #%d received\n", pmt->program_number);
1880
1881                for (i=0; i<av->pat->numPrograms; i++) {
1882                        if (av->pat->programs[i].program_number == pmt->program_number)
1883                                break;
1884                }
1885                if (i >= av->pat->numPrograms) {
1886                        dprint(0, "!! pmt #%d received, but not in pat list\n", pmt->program_number);
1887                        goto label_exit;
1888                }
1889                if (!av->pmtList) {
1890                        dprint(0, "!! pmt received without pmtlist\n");
1891                        goto label_exit;
1892                }
1893                if (av->pmtList[i]) {
1894                        dprint(2, "pmt[%d] already exist. #%d\n", i, av->pmtList[i]->program_number);
1895                }
1896                else {
1897                        av->pmtList[i] = pmt;
1898                        pmt = NULL;
1899                }
1900                // ÀÌÁ¦ ´Ù¸¥ program pmt°¡ ´õ ÀÖ´ÂÁö ã¾Æº»´Ù.
1901                //doDmc_StartAllPmtMonitor(av);
1902               
1903                goto label_exit;
1904        }
1905#endif // USE_CH_MW_ALL_PMT_DOWNLOAD
1906
1907        if (g_Trace_bDmcPsiEvent) {
1908                dprint(2, "PMT change event! PID %d, program_num %d, version %d\n",
1909                        pmt->PID, pmt->program_number, pmt->version_number);
1910        }
1911       
1912        // compare
1913        // ±âÁ¸ÀÇ PMT¶û ºñ±³¸¦ ÇØº»´Ù. µ¿ÀÏÇÑ PMT·Î ÆÇ¸íµÇ¸é °è¼Ó ÁøÇàÇÒ Çʿ䰡 ¾ø´Ù.
1914        //
1915        if (dmc_bIgnoreEquivPmt) 
1916        {
1917                int diff;
1918                diff = Dmc_CheckPmtDifference(av->pmt, pmt);
1919                if (diff == 0) {
1920                        if (g_Trace_bDmcPsiEvent)
1921                                dprint(2, "!! Same PMT is already active..\n");
1922                        //FreePMT(pmt); // ¾Æ·¡¿¡¼­ µ¿½Ã¿¡ free ÇÔ.
1923                        goto label_exit;
1924                }
1925                if (g_Trace_bDmcPsiEvent)
1926                        dprint(2, "\t new pmt, difference point is %d\n", diff);
1927        }
1928       
1929        // process new PMT..
1930        //
1931        pmt_pid        = pmt->PID;
1932        program_number = pmt->program_number;
1933       
1934        videoPID = audioPID = pcrPID = 0;
1935
1936        // MW µðÆúÆ® ¼±Åà ·ÎÁ÷¿¡ ÀÇÇØ °¢ stream º° pid¸¦ ¼±ÅÃÇÑ´Ù.
1937        status = Dmc_DecidePidInfo(pmt, NULL, &psiPid, 0);
1938
1939        if (status == statusOK && psiPid.bValid) {
1940                videoPID = psiPid.video;
1941                audioPID = psiPid.audio;
1942                pcrPID   = psiPid.pcr;
1943                videoType = psiPid.videoType;
1944                audioType = psiPid.audioType;
1945        }
1946        else
1947                dprint(2, "!! pid from pmt err %d\n", status);
1948
1949        // application callback¿¡ ÀÇÇÑ override¸¦ ó¸®ÇÑ´Ù.
1950        // ¸¸¾à callbackÀÌ µî·Ï ¾ÈµÈ °æ¿ì¶ó¸é ¾Õ¿¡¼­ ¼±ÅÃµÈ °ªÀÌ ±×´ë·Î »ç¿ëµÇ¾î¾ß ÇÑ´Ù.
1951        doDmc_SelectAudioStream(pmt, NULL, &audioPID, &audioType);
1952        doDmc_SelectVideoStream(pmt, NULL, &videoPID, &videoType);
1953       
1954        if (pcrPID == 0 || (videoPID == 0 && audioPID == 0)) {
1955                dprint(0, "!! No valid PIDs in PMT. p%d/v%d/a%d, ignored.\n", 
1956                                                pcrPID, videoPID, audioPID);
1957                                               
1958                //if (pmt) FreePMT(pmt); // ¾Æ·¡¿¡¼­ µ¿½Ã¿¡ ¼öÇà..
1959                //pmt = NULL;
1960               
1961                // ´Ù½Ã Çѹø ´õ ÇöÀç PMT ¼ö½ÅÀ» ½ÃµµÇØ º¸´Â°Ô ÁÁ°Ú´Ù.
1962                //
1963                dmc_nPmtChangeRetryCount++;
1964                goto label_retry_pmt_monitor;  // cafrii 030916
1965        }
1966       
1967        if (dmc_bIgnoreEquivPmt) 
1968        {
1969                // ¾Ë¾Æ³½ PID°¡ ÇöÀç PID¿Í µ¿ÀÏÇÏ´Ù¸é Restart¸¦ ÇÒ Çʿ䰡 ¾øÀ» ¼öµµ ÀÖ´Ù.
1970                //
1971                // NOTE! descriptor°¡ º¯°æµÇ¾úÀ» ¼öµµ ÀÖÀ¸¹Ç·Î app noti´Â »©¸ÔÀ¸¸é ¾ÈµÊ.
1972               
1973                // todo.. ¾Æ·¡ Äڵ尡 ÇÊ¿äÇÑ ÀÌÀ¯´Â?
1974                // cafrii 030916, Only Audio dropÀÇ °æ¿ì¿¡´Â PmtChange¸¦ ¹«½ÃÇϵµ·Ï ÇÏ¿´´Ù.
1975                // Audio°¡ ³ª¿À´Ù°¡ ±×³É ¹«À½ »óÅ·θ¸ µÉ °ÍÀÌ´Ù.
1976                //
1977               
1978        //      dprint(1,"av->video_type(%d), videoType(%d)\n", av->video_type, videoType);
1979               
1980                if (av->video_pid == videoPID && av->video_type == videoType &&
1981                        (       (av->audio_pid == audioPID)
1982                                /* || (prev_av.audio_pid != 0 && audioPID == 0) */ ) &&
1983                        av->pcr_pid == pcrPID)
1984                {
1985                        // PMT°¡ ignore µÈ °æ¿ì¶óµµ ¸î°¡Áö ó¸®ÇØÁÙ ÀÛ¾÷µéÀÌ ÀÖ´Ù. ÀÌ °÷¿¡¼­ ¼öÇà.
1986                        //
1987                        if (g_Trace_bDmcPsiEvent)
1988                                dprint(2, "!! PMT is ignored. similar & active context already running..\n");
1989                       
1990                        av->program_number = pmt->program_number;
1991                       
1992                        // PmtChange´Â ¾î·µç ¼º°øÀûÀ¸·Î µÈ °ÍÀ̹ǷΠ0À¸·Î ¸®¼Â.
1993                        //
1994                        dmc_nPmtChangeRetryCount = 0;
1995
1996                        doDmc_UpdatePsiInfo(NULL, pmt); // pmt´Â ÀÌ ³»ºÎ¿¡¼­ º°µµ ÀúÀåÇÑ´Ù.
1997                        pmt = NULL;
1998       
1999                        goto label_completed;
2000                }
2001                else
2002                        dprint(2, "\t pid diff. pva %x %x %x != %x %x %x\n",
2003                                                av->pcr_pid, av->video_pid, av->audio_pid,
2004                                                pcrPID, videoPID, audioPID);
2005        }
2006
2007        doDmc_UpdatePsiInfo(NULL, pmt); // pmt´Â ÀÌ ³»ºÎ¿¡¼­ º°µµ ÀúÀåÇÑ´Ù.
2008        pmt = NULL;
2009
2010       
2011        // backup av info because other essential parameters are preserved.
2012        prev_av = *av;
2013
2014        // cafrii 081125 add
2015        // ¸¸¾à audio pid¸¸ º¯°æµÈ °æ¿ì¶ó¸é (¶Ç´Â audio°¡ ¾ø´Ù°¡ ½ÃÀÛÇÏ´Â °æ¿ì¶ó¸é)
2016        // audio¸¸ restart ÇÏ¸é µÈ´Ù.
2017        //
2018        // cafrii 090212 bugfix
2019        // »õ audio PID°¡ 0ÀÎ °æ¿ì StartDigital¿¡¼­ ¿À·ù ¹ß»ýÇÏ´Â ¹®Á¦ ¹ß°ß.
2020        // video°¡ Á¤»óÀûÀÎ °æ¿ì, ±×¸®°í »õ audio PID°¡ Á¤»óÀûÀÎ °æ¿ì¿¡¸¸
2021        // audio restart only ¹æ¹ýÀ» Á¦ÇÑÀûÀ¸·Î Àû¿ëÇÑ´Ù.
2022        // »õ audio pid°¡ 0ÀÎ °æ¿ì È­¸éÀÌ 1¹ø ±ôºýÇÏ´Â °æ¿ì ÀÖ´Ù.
2023
2024#if 1 // NEW_DHL_API
2025        if (1) {
2026                tDHL_VideoStatus video_status;
2027                DHL_AV_VideoGetStatus(0, &video_status);
2028                bVideoOutputExist = video_status.bOutputExist;
2029        }
2030#else
2031        bVideoOutputExist = DHL_AV_VideoOutputExist();
2032#endif
2033        if (av->video_pid == videoPID && av->video_type==videoType && bVideoOutputExist && audioPID)
2034        {
2035                doDmc_StopDigitalAudio();
2036
2037                // video pid¸¦ 0À¸·Î ÁöÁ¤Çϸé audio¸¸ play ÇÑ´Ù.
2038                status = doDmc_StartDigital(0, audioPID, pcrPID, (DMC_VIDEO_CACHE)NULL, videoType, audioType);
2039        }
2040        else 
2041        {
2042                doDmc_StopDigital(FALSE, FALSE); // do not cancel monitors
2043
2044                status = doDmc_StartDigital(videoPID, audioPID, pcrPID, (DMC_VIDEO_CACHE)NULL, videoType, audioType);
2045                        // Note!!
2046                        // ÀÌ ÇÔ¼ö¸¦ ºÎ¸£´Â ¼ø°£¿¡ video°¡ runningÁßÀ̶ó¸é,
2047                        // ÀÌ ÇÔ¼ö ¾È¿¡¼­ ±âÁ¸ÀÇ video context¸¦ °­Á¦ stop ½ÃŰ¸é¼­ µ¿½Ã¿¡ MonitorPATµµ ÇØÁ¦µÈ´Ù.
2048                        // ¹Ýµå½Ã ¹Ì¸®¹Ì¸® light stopÀ» ½ÃÄѳõ¾Æ¼­ ¾È¿¡¼­ ÀÚµ¿ stop µÇ´ÂÀÏÀÌ ¾øµµ·Ï ÇÏÀÚ.
2049                        //
2050        }
2051       
2052        if (status == statusCancelled) {
2053                dprint(1, "\tStartDigital in PMT change cancelled by user\n");
2054                doDmc_ClearProgramInfo();
2055               
2056                // cancelÀÌ µÈ °æ¿ì´Â °ð¹Ù·Î ´Ù¸¥ decodingÀ» ½ÃÀÛÇÒ °ÍÀ̱⠶§¹®¿¡
2057                // retryµµ ¾ÈÇϰí callbackµµ ¾ÈÇÑ´Ù.
2058                goto label_exit;
2059        }
2060        else if (status) { // timeout Errorµµ Æ÷ÇÔ..
2061               
2062                dprint(0, "!! RestartVideo by NewPMT err %d\n", status);
2063                doDmc_ClearProgramInfo();
2064               
2065                // ´Ù½Ã Çѹø ´õ PMT ¼ö½Å ½Ãµµ.. ¾Æ¸¶ ¼öÁýµÈ PID°¡ À߸øµÈ °ÍÀÏ ¼ö ÀÖ´Ù.
2066                //
2067                dmc_nPmtChangeRetryCount++;
2068                goto label_retry_pmt_monitor;
2069        }
2070       
2071        doDmc_UpdateProgramInfoDigital(prev_av.rf, prev_av.mod,
2072                                prev_av.method, prev_av.major, prev_av.minor,
2073                                av->pmt->program_number,
2074                                videoPID, audioPID, pcrPID, videoType, audioType);
2075                // program number¸¸Àº ±âÁ¸ °Í°ú ´Ù¸¦ ¼öµµ ÀÖ´Ù. ÀÌ Çڵ鷯¿¡¼­ ó¸® Áß¿¡
2076                // »õ PMT¿¡¼­ program_number°¡ ¹Ù²î¾úÀ» ¼öµµ ÀÖÀ¸¹Ç·Î..
2077       
2078        dmc_nPmtChangeRetryCount = 0; // ¼º°øÇßÀ¸¹Ç·Î 0À¸·Î ¸®¼ÂÇÑ´Ù.
2079
2080label_completed:
2081
2082        if (1) // Notify to user. ApplicationÀ¸·Î PmtChange event¸¦ º¸³½´Ù.
2083        {
2084                PSIChangeNotifyInfo pcni;
2085                memset(&pcni, 0, sizeof(pcni));
2086       
2087                pcni.pmtchanged = TRUE; // This is PMT
2088                pcni.pmt = av->pmt;          // new PMT
2089                pcni.pat = av->pat;          // new or existing PAT
2090                //pcni.ignore = FALSE;  // This is [out] parameter. FALSE by default
2091
2092                // cafrii 060804 add two more parameters.
2093                pcni.userParam = av->userParam;
2094                pcni.av = av;
2095               
2096                doDmc_Notify(DMC_NOTIFY_PMTChanged, (UINT32)&pcni);             
2097
2098                // arzhna, 100203
2099                // CA PMT¸¦ Àü´ÞÇϱâ À§ÇÑ callback È£Ãâ
2100                doDmc_Notify(DMC_NOTIFY_CaPmt, (UINT32)&pcni);         
2101        }
2102       
2103label_exit:
2104
2105#if USE_CH_MW_ALL_PMT_DOWNLOAD
2106        doDmc_StartAllPmtMonitor(av);
2107#endif
2108
2109        // cafrii 060830 add bugfix!! memory leak for some odd case..
2110        if (pmt) 
2111        {
2112#if DMC_CHECK_HEAP_SIZE
2113                UINT32 heap_before = DHL_GetFreeHeapSize(0);
2114                FreePMT(pmt);
2115                dprint(2, "free pmt 0x%x.. heap %u->%u\n", 
2116                        pmt, heap_before, DHL_GetFreeHeapSize(0));
2117#else
2118                FreePMT(pmt);
2119                dprint(2, "free pmt 0x%x..\n", pmt);
2120#endif
2121        }
2122
2123        Dmc_UnlockAVMutex();
2124        return;
2125
2126
2127label_retry_pmt_monitor:
2128
2129        // cafrii 060830 add bugfix!! memory leak for some odd case..
2130        if (pmt) {
2131                dprint(2, "free pmt 0x%x..\n", pmt);
2132                FreePMT(pmt);
2133        }
2134
2135        // 1. ¼ö½ÅµÈ PMTÀÇ ³»¿ë¿¡ ¹®Á¦°¡ ÀÖÀ»¶§ (PID °Ë»ö ºÒ°¡, ¶Ç´Â À߸øµÈ PID)
2136        // 2. A/V decoding µµÁß¿¡ ¹®Á¦°¡ »ý°åÀ» ¶§
2137        //
2138        dprint(0, "!! PMT change error! retry count %d\n", dmc_nPmtChangeRetryCount);
2139       
2140        // ApplicationÀ¸·Î callbackÀ» ÇÒ °æ¿ì..
2141        //
2142        // doDmc_Notify(DMC_NOTIFY_PMTChangeError, 0);
2143                // applicationÀº ÀÌ ·çƾ¿¡¼­ ¸ðÁ¾ÀÇ Á¶Ä¡¸¦ ÃëÇØ¾ß ÇÑ´Ù.
2144                // ÇöÀç video´Â ¾È³ª¿À°í ÀÖÀ» ¼öµµ ÀÖ´Ù.
2145       
2146        if (dmc_nPmtChangeRetryCount > dmc_LimitPmtChangeRetryCount) {
2147                dprint(0, "!! PMT change error retry count is over MAX %d, Ignore PmtChange!!\n", 
2148                                dmc_nPmtChangeRetryCount);
2149                //return;
2150                goto label_retry_exit;
2151        }
2152
2153       
2154        if (pmt_pid <= 0 || pmt_pid >= 0x1FFF)
2155        {
2156                dprint(0, "!! pmt pid 0x%x invalid\n", pmt_pid);
2157        }
2158        else
2159        {
2160                DHL_PSI_StopMonitor(av->pmtPsiCtl);
2161                av->pmtPsiCtl = (tDHL_PSI_ControlHandle)0;
2162
2163                err = MonitorPMT(Dmc_GetCurrentTsd(),
2164                                                 pmt_pid,
2165                                                 program_number,
2166                                                 TRUE, // current
2167                                                 dmc_PmtUpdateMode,
2168                                                 _Dmc_PmtEventProc,
2169                                                 0,   // userParam
2170                                                 &av->pmtPsiCtl);
2171                if (err) {
2172                        dprint(0, "!! MonitorPMT returned %s\n", ErrorString(err));
2173                }
2174        }
2175
2176label_retry_exit:
2177
2178#if USE_CH_MW_ALL_PMT_DOWNLOAD
2179        doDmc_StartAllPmtMonitor(av);
2180#endif
2181
2182        Dmc_UnlockAVMutex();
2183       
2184}
2185
2186
2187
2188/*
2189 * handleImportantVideoChange is called from within the video control task
2190 * in response to an importantChange event which was in turn sent by the higher priority
2191 * video driver task. The change has already occurred and this is an after-the-fact notification.
2192 * We use this mostly to handle output=input mode
2193 */
2194void doDmc_HandleImportantVideoChange(DmcMessage *pmsg)
2195{
2196        BOOL bFormatChanged = FALSE;
2197        DHL_RESULT dhr;
2198       
2199        dprint(1, "evtVideoImportantChange: cid %d\n", pmsg->cancelId);
2200       
2201        // todo..
2202        // ÀÌ ½ÃÁ¡¿¡¼­ ÀÌ¹Ì driverÀÇ video context°¡ »õ·Î¿î Á¤º¸·Î °»½ÅµÈ °ÍÀΰ¡?
2203       
2204        bFormatChanged = doDmc_CheckIfFormatChanged();
2205       
2206        if (bFormatChanged == FALSE) {
2207                dprint(2, "\t  source format not changed. keep current timing..\n");
2208                // important video change ÀÇ °æ¿ì¿¡´Â format ÀÌ unchangeµÈ °æ¿ì¿¡´Â
2209                // notifyµîÀÇ ÀÛ¾÷À» ÀüÇô ÇÒ Çʿ䰡 ¾ø´Ù.
2210                return;
2211        }
2212       
2213        // todo..
2214        // user¿¡°Ô callbackÀ¸·Î notificationÀ» Çϰí
2215        // ÇÊ¿äÇÑ °æ¿ì timing change¸¦ ÇÑ´Ù.
2216        //
2217
2218        // cafrii 070725 add
2219        //   runtime ½Ã¿¡ ÇØ»óµµ º¯°æµÇ´Â ½ºÆ®¸² Áö¿ø.
2220        doDmc_ProcessScreenAdjustment();
2221
2222        // restore video temp-mute
2223       
2224        dmc_bRequestVideoHide &= ~DMC_VIDEO_HIDE_VIDEO_START;
2225        dprint(2, "check video temp-mute.. 0x%x\n", dmc_bRequestVideoHide);
2226        if (dmc_bRequestVideoHide == 0) {
2227                dhr = DHL_AV_VideoHide(0, FALSE);
2228                if (dhr)
2229                        dprint(0, "!! video unblank err\n", dhr);
2230        }
2231
2232} // doDmc_HandleImportantVideoChange
2233
2234
2235void doDmc_HandleUserChange(DmcMessage *pmsg)
2236{
2237        // µðÆúÆ®·Î driver¿¡¼­ ¼öÇàÇÏ´Â ÀÛ¾÷À¸·Î ¸¸Á·ÇÑ´Ù.
2238       
2239}
2240
2241
2242void doDmc_HandleMajorVideoChange(DmcMessage *pmsg)
2243{
2244        STATUS status;
2245        ProgramAVInfo prev_av;
2246       
2247        MajorChangeEventParam arg;
2248       
2249
2250        // ¾î¶² °æ¿ì¿¡ ÀÌ major event°¡ ¿À´Â°¡?
2251        // --> majorchange video event.
2252        //    ¹öÆÛ°¡ ºÎÁ·ÇÒ °æ¿ì expand ½Ã۱â À§ÇØ ºÒ¸°´Ù.
2253        //    Áï ÇöÀç »óÅ ±×´ë·Î¿¡¼­ ´Ù½Ã video context¸¸ ´Ù½Ã ¸¸µé¸é µÉ µí ÇÏ´Ù.
2254        //
2255        // ÈÄ󸮷ΠPAT monitoringÀ» ´Ù½Ã ÇÏ´Â°Ô Àû´çÇѰ¡?
2256        // --> ¿ì¸®´Â ÇöÀç PID Á¤º¸¸¦ ´Ù °¡Áö°í Àֱ⠶§¹®¿¡ À̸¦ Ȱ¿ëÇØ¼­ AV start¸¸ Çϰí,
2257        //     psiMonitorControlÀº °Çµå¸®Áö ¾Ê´Â´Ù.
2258        //
2259        ProgramAVInfo *av = Dmc_LockAVMutex();
2260
2261        dprint(1, "evtVideoMajorChange: cid %d\n", pmsg->cancelId);
2262
2263        // cafrii 060814 add
2264        //   US14 streamÀÇ °æ¿ì important change°¡ 1ȸ È£ÃâµÇ°í ³ª¼­
2265        //   ±× ÀÌÈÄ major change event°¡ ¿¬´Þ¾Æ¼­ 4ȸ ¹ß»ýÇÑ´Ù.
2266        //   ¹Ì·¡¿¡ major change°¡ ¹ß°ßµÇ´Â °æ¿ì 󸮸¦ ÇÏÁö ¾Ê°í ¹Ì·çµµ·Ï ÇÏÀÚ.
2267        //
2268        if (doDmc_CheckMsgExist(evtVideoMajorChange)) {
2269                dprint(2, "!! Future Major Change event detected. ignore this..\n");
2270                goto label_exit;
2271        }
2272
2273        if (!av->active || av->analog) {
2274                dprint(0, "!! illegal state (%s, %d)! majorVideoChange ignored.\n",
2275                        av->active ? "active" : "inactive",
2276                        av->analog ? "analog" : "digital");
2277                goto label_exit;
2278        }
2279
2280        if (1) {  // application notification
2281                memset(&arg, 0, sizeof(arg));
2282                arg.ignore = FALSE; // cafrii 060519, TRUE->FALSE
2283
2284                doDmc_Notify(DMW_NOTIFY_MajorChangeEvent, (UINT32)&arg);
2285                if (arg.ignore) {
2286                        dprint(2, "!! User want to ignore this MajorChange event.. skip.\n");
2287                        goto label_exit;
2288                }
2289        }
2290       
2291        dprint(2, "\tPreviously tuned %s\n", TuneMethodString(av->method));
2292       
2293        prev_av = *av;
2294       
2295        // video context¸¸À» »èÁ¦ÇÑ´Ù. ´Ù¸¥ °ÍµéÀº »èÁ¦ÇÏÁö ¾Ê´Â´Ù.
2296        //
2297        doDmc_StopDigital(FALSE, FALSE); // do not cancel monitors
2298
2299        status = doDmc_StartDigital(prev_av.video_pid, prev_av.audio_pid, 
2300                                                                prev_av.pcr_pid, (DMC_VIDEO_CACHE)NULL, prev_av.video_type, prev_av.audio_type);
2301
2302        if (status == statusCancelled) {
2303                dprint(0, "!! StartDigital in MajorChange cancelled by user\n");
2304                doDmc_ClearProgramInfo();
2305               
2306                // cancelÀÌ µÈ °æ¿ì´Â °ð¹Ù·Î ´Ù¸¥ decodingÀ» ½ÃÀÛÇÒ °ÍÀ̱⠶§¹®¿¡
2307                // retryµµ ¾ÈÇϰí callbackµµ ¾ÈÇÑ´Ù.
2308        }
2309        else if (status) {
2310                dprint(0, "!! restart video error %d in major change event!\n", status);
2311                doDmc_ClearProgramInfo();
2312               
2313                // ´Ù½Ã Çѹø ½Ãµµ¸¦ ÇÒ ¹æ¹ýÀÌ Àִ°¡?
2314                //
2315        }
2316        else {
2317                // success!!
2318                //
2319                doDmc_UpdateProgramInfoDigital(prev_av.rf, prev_av.mod,
2320                                        prev_av.method, prev_av.major, prev_av.minor,
2321                                        prev_av.program_number,
2322                                        prev_av.video_pid, prev_av.audio_pid, prev_av.pcr_pid, prev_av.video_type, prev_av.audio_type);
2323        }
2324
2325label_exit:
2326
2327        Dmc_UnlockAVMutex();
2328
2329} // doDmc_HandleMajorVideoChange
2330
2331
2332
2333void doDmc_HandleFreezeVideoEnd(DmcMessage *pmsg)
2334{
2335        // ´ëºÎºÐÀÇ ÀÛ¾÷Àº video driver¿¡¼­ ó¸®ÇÏ¿´À¸¸ç,
2336        // application¿¡ Å뺸ÀÇ ¸ñÀûÀ¸·Î À̺¥Æ®¸¦ ¹Þ´Â´Ù.
2337
2338        dprint(1, "eventFreezeVideoEnd: cid %d\n", pmsg->cancelId);
2339
2340        if (dmc_bWaitFirstFreezeVideoEndEvent) // ÇöÀç wait ÁßÀ̸é..
2341        {
2342                BOOL bProcessed = FALSE;
2343               
2344                dprint(2, "\tfirst FreezeEndEvent\n");
2345               
2346                doDmc_Notify(DMW_NOTIFY_VideoFreezeEndEvent, (UINT32) &bProcessed);
2347               
2348                // Zoran decoder¿¡¼­´Â ÀϹÝÀûÀ¸·Î óÀ½¿¡ µÎ°³ÀÇ freeze video end
2349                // event°¡ ¹ß»ýÇϰí ÀÖ´Ù. óÀ½°Í ¿Ü¿¡´Â Çʿ䰡 ¾ø±â ¶§¹®¿¡
2350                // Ȥ½Ã msgQ ¿¡ Á¸ÀçÇÏ´Â µ¿ÀÏ event´Â »èÁ¦ÇØÁÖ¸é ÁÁ´Ù.
2351                //
2352                doDmc_DeleteMsg(evtFreezeVideoEnd);
2353
2354                if (bProcessed == FALSE) 
2355                {
2356                        //dprint(2, "\tAudio TempMute Off in First video frame\n");
2357                        // cafrii, 030610, channel change½Ã¿¡ Audio Pop noise¸¦ ¸·±â À§ÇØ,
2358                        //   stop video¿¡¼­ Audio mute, freeze_end½Ã¿¡ mute off¸¦ ÇÑ´Ù.
2359
2360                        dprint(2, "\t  audio temp mute off\n");
2361                        doDmc_AudioTempMute(FALSE);
2362                       
2363                        // Ç×»ó TempMuteOff¸¦ ÇÒ ÇÊ¿ä´Â ¾ø°í, ¿ø·¡´Â ƯÁ¤ Á¶°ÇÀÌ µÉ¶§¸¸ ÇØ¾ßÇÑ´Ù.
2364                        //
2365                        // dmc_bUseAudioTempMuteAtStart == TRUE
2366                        // dmc_bAudioVideoSyncStart == TRUE
2367                        //
2368                        // À§ µÎ Á¶°ÇÀÌ TRUE°¡ ¾Æ´Ï¸é TempMute°¡ ¾ÈµÈ »óÅÂÀÌ´Ù.
2369                        // ±×·¯³ª TempMuteOff¸¦ ¿©·¯¹ø È£ÃâÇÑ´Ù°í ¹®Á¦°¡ µÇ´Â°ÍÀÌ ¾Æ´Ï¹Ç·Î
2370                        // ¿©±â¼­´Â ±×³É ¹«Á¶°Ç È£ÃâÇØÁÖµµ·Ï ÇÏÀÚ.
2371                }
2372               
2373                dmc_bWaitFirstFreezeVideoEndEvent = FALSE;
2374        }
2375        return;
2376}
2377
2378
2379
2380// cafrii 060721 add
2381void doDmc_HandleVideoScrambled(DmcMessage *pmsg)
2382{
2383        // cafrii 060831 comment
2384        //
2385        // °£È¤ driver¿¡¼­ Á¤»óÀûÀÎ ½ºÆ®¸²Àε¥µµ driver¿¡¼­ scrambled event¸¦ º¸³»ÁÙ ¶§°¡ ÀÖ´Ù.
2386        // ÀÌ °æ¿ì Çѹø¿¡ scrambleÀ̶ó°í ÆÇ´ÜÇϱ⿡´Â À§ÇèÇÑ ¸éÀÌ ÀÖ´Ù.
2387        //
2388        // ´ëÃ¥ 1.
2389        //   scramble check¸¦ ÀÏÁ¤ ½Ã°£ ³»¿¡ ÀÏÁ¤ Ƚ¼ö ÀÌ»ó report µÉ ¶§¿¡¸¸ actionÀ» ÃëÇÑ´Ù.
2390        //   driver¿¡ °ü·Ã API°¡ Á¦°øµÇ¾î¾ß ÇÔ.
2391        //
2392        // ´ëÃ¥ 2.
2393        //   runtime Áß¿¡´Â scramble event¿¡ ´ëÇØ¼­ ´ëÀÀÇÏÁö ¾Ê´Â´Ù.
2394        //   Ã³À½ ½ÃÀÛÇÒ ¶§¿¡ ´ëÀÀ ÇÏ´Â °ÍÀ¸·Î ÃæºÐ.
2395
2396#if 0
2397        // cafrii 060831 delete code, use policy #2.
2398       
2399        // video ½ÃÀÛÇÒ ¶§ °¡ ¾Æ´Ï¶ó runtime Áß¿¡ scramble·Î º¯°æµÈ °æ¿ì ¹ß»ý.
2400        // SigMon µî¿¡¼­ NoProgram / AudioOnly banner¸¦ ¶ç¿ï ¼ö ÀÖµµ·Ï Á¶Ä¡ÇÑ´Ù.
2401        //
2402
2403        BOOL bAudioExist;
2404       
2405        // ¸¸¾à audioµµ ¾ø´Â »óŶó¸é ¿ÏÀüÈ÷ ³»·Á¾ß ÇÑ´Ù.
2406        // 1ȸ¸¸ Ã¼Å©ÇØµµ ¾ÈÀüÇѰ¡?
2407        //
2408        {
2409                ProgramAVInfo *av = Dmc_LockAVMutex();
2410
2411                dprint(2, "\t \n", av->rf, av->program_number);
2412                DHL_AV_SaveVideoToCache(av->rf, av->program_number);
2413
2414                Dmc_UnlockAVMutex();
2415        }
2416
2417       
2418        bAudioExist = DHL_AV_AudioOutputExist();
2419
2420        if (bAudioExist == FALSE)
2421        {
2422                dprint(2, "video scrambled and no audio detect. stop!\n");
2423
2424                doDmc_StopDigital(TRUE, FALSE);
2425        }
2426        else
2427        {
2428                // video context¸¸ ³»¸°´Ù.
2429                //
2430                dprint(2, "audio detected. stop video only\n");
2431               
2432                doDmc_StopDigitalVideo(FALSE);
2433                        // cache¿¡´Â ÀúÀåÇÏÁö ¸»ÀÚ. scramble µÈ °ÍÀ̶ó¸é Àǹ̰¡ ¾øÀ½.
2434
2435        }
2436#endif
2437
2438}
2439
2440
2441#if COMMENT
2442_______AVControl________(){}
2443#endif
2444
2445
2446
2447void doDmc_StopDigitalVideo(BOOL bSaveToCache)
2448{
2449        DHL_RESULT dhlResult;
2450
2451        dprint(2, "     \tstop digital video..\n");
2452
2453#if 0 // NEW_DHL_API
2454        // decoding°ú display±îÁö ¸ðµÎ stopÇÑ´Ù.
2455        //
2456        DHL_AV_DispStop();
2457#endif
2458
2459#if SUPPORT_DMW_VIDEO_CACHE
2460        if (bSaveToCache) // cafrii 060630 add
2461        {
2462                ProgramAVInfo *av;
2463                av = Dmc_LockAVMutex();
2464
2465                dprint(2, "\tsave video to cache.. rf %d, #%d..\n", av->rf, av->program_number);
2466
2467                DHL_AV_SaveVideoToCache(av->rf, av->program_number);
2468
2469                Dmc_UnlockAVMutex();
2470        }
2471#endif
2472       
2473        dhlResult = DHL_AV_VideoStop(0);
2474        if (dhlResult)
2475                dprint(0, "!! DHL_AV_VideoStop err 0x%x\n", dhlResult);
2476
2477}
2478
2479
2480void doDmc_StopDigitalAudio(void)
2481{
2482        AudioDecodeStopParam adsp;
2483        DHL_RESULT dhlResult;
2484
2485        dprint(2, "\tstop digital audio..\n");
2486       
2487        memset(&adsp, 0, sizeof(AudioDecodeStopParam));
2488        //adsp.mode = MOCHA_ATSC_INPUT;
2489        adsp.result = statusNotImpl;  // my default.
2490
2491        doDmc_Notify(DMW_NOTIFY_AudioDecodeStop, (UINT32) &adsp);
2492       
2493        if (adsp.result == statusNotImpl) {
2494                // µðÆúÆ® ±¸Çö:
2495            dhlResult = DHL_AV_AudioStop();
2496            if (dhlResult)
2497                    dprint(0, "!! DHL_AV_AudioStop err 0x%x\n", dhlResult);
2498        }
2499        else if (adsp.result == statusOK) {
2500                // Ưº°È÷ ÇÒÀÏ ¾øÀ½.
2501        }
2502
2503}
2504
2505//
2506// tsd stop, routing µîÀº ¼öÇàÇÏÁö ¾Ê°í ¿ÀÁ÷ decoding ¸¸ ÁßÁöÇÑ´Ù.
2507//
2508void doDmc_StopDigital(BOOL bCancelMonitors, BOOL bSaveToCache)
2509{
2510        if (!Dmc_IsDmcTask()) {
2511                dprint(0, "!! doDmc_StopDigital() should be called only in DmcTask.\n");
2512                return;
2513        }
2514
2515        dprint(1, "\tStop digital video/audio, cancel monitor %d\n", bCancelMonitors);
2516       
2517        dmc_bWaitFirstFreezeVideoEndEvent = FALSE;
2518
2519        // ´õÀÌ»ó Áö¿øÇÏÁö ¾ÊÀ½.
2520        //if (_Dmc_DecodeStopCallback)
2521        //      _Dmc_DecodeStopCallback(0, 0);  // ÇöÀç´Â Ưº°ÇÑ parameter°¡ ¾øÀ½..
2522
2523        doDmc_StopDigitalAudio();
2524
2525        doDmc_StopDigitalVideo(bSaveToCache);
2526       
2527        if (bCancelMonitors)
2528        {
2529                doDmc_CancelMonitors();
2530
2531                // StopÀÌ µÇ¸é¼­ Psi Monitor ControlÀÌ »èÁ¦µÇ¾úÀ¸¹Ç·Î
2532                // ÀÌ¹Ì DmcQ¿¡ µé¾î¿Í ÀÖ´Â ¸ðµç Psi À̺¥Æ®µéµµ ´Ù ½ÄÁ¦ÇØ¾ß ÇÑ´Ù.
2533                //
2534                // ´Ü vxWorks message QÀÇ ÇѰè·Î »õ ¹æ½ÄÀÇ UserQue¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¸é ÀÌ ±â´ÉÀ» ¼öÇàÇÒ ¼ö ¾ø´Ù.
2535               
2536                dprint(2, "\t Delete all event message..\n");
2537                doDmc_DeleteAllEventMsg();
2538                        // ¸ðµç event¸¦ Q¿¡¼­ »èÁ¦..
2539        }
2540
2541        doDmc_ClearProgramInfo(); // cafrii 060721 add
2542
2543}
2544
2545
2546void doDmc_StopAnalog()
2547{
2548        DHL_RESULT dhlResult;
2549        AudioDecodeStopParam adsp;
2550
2551        if (!Dmc_IsDmcTask()) {
2552                dprint(0, "!! doDmc_StopAnalog() should be called only in DmcTask.\n");
2553                return;
2554        }
2555
2556        dprint(1, "\tStop analog video/audio\n");
2557
2558        //--------------- Audio Stop --------------
2559        memset(&adsp, 0, sizeof(AudioDecodeStopParam));
2560       
2561        adsp.result = statusNotImpl;  // my default.
2562        //adsp.mode = MOCHA_NTSC_INPUT;
2563
2564        doDmc_Notify(DMW_NOTIFY_AudioDecodeStop, (UINT32) &adsp);
2565       
2566        if (adsp.result == statusNotImpl) {
2567                // µðÆúÆ® ±¸Çö:
2568                dhlResult = DHL_CAP_AudioStop();
2569                if (dhlResult)
2570                        dprint(0, "!! DHL_CAP_AudioStop err 0x%x\n", dhlResult);
2571        }
2572
2573        //--------------- Video Stop --------------
2574        dhlResult = DHL_CAP_VideoStop(0);
2575        if (dhlResult)
2576                dprint(0, "!! DHL_CAP_VideoStop err 0x%x\n", dhlResult);
2577
2578       
2579        // Stop context¸¦ ÇÒ ¶§ µðÆúÆ® »óÅ·ΠplaneÀ» º¸ÀÌ°Ô ÇÒ °ÍÀÎÁö ¾Æ´ÑÁö´Â ¾Ë¾Æ¼­ °áÁ¤..
2580#if 0
2581        DHL_AV_VideoHide(FALSE);
2582       
2583        av = Dmc_LockAVMutex();
2584        av->video_hidden = FALSE;
2585        Dmc_UnlockAVMutex();
2586#endif // 0
2587
2588        doDmc_ClearProgramInfo(); // cafrii 060721 add
2589
2590
2591}
2592
2593void doDmc_Stop()
2594{
2595        ProgramAVInfo *av;
2596       
2597        if (!Dmc_IsDmcTask()) {
2598                dprint(0, "!! doDmc_Stop() should be called only in DmcTask.\n");
2599                return;
2600        }
2601
2602        av = Dmc_LockAVMutex();
2603       
2604        dprint(2, "doDmc_Stop: current activity %d\n", av->active);
2605
2606        if (av->active) 
2607        {
2608                if (av->analog) {
2609                        dprint(2, "Stop Analog TV\n");
2610                        doDmc_StopAnalog();
2611                }
2612                else {
2613                        dprint(2, "Stop Digital TV\n");
2614                        doDmc_StopDigital(TRUE, TRUE); // cancel all monitors
2615                }
2616        }
2617        else 
2618        {
2619                dprint(2, "    video already stopped.\n");
2620        }       
2621
2622        doDmc_ClearProgramInfo(); // cafrii 060721 add
2623       
2624        // cafrii 030917
2625        // TunerÀÇ ÀÌ»ó µîÀ¸·Î ÇØ¼­ context°¡ ±âµ¿ÀÌ ¾ÈµÈ °æ¿ì, inactive »óÅÂÀÌÁö¸¸
2626        // application¿¡¼­ PsiMonitor¸¸ º°µµ·Î launchÇßÀ» ¼öµµ ÀÖ´Ù.
2627        // µû¶ó¼­ À§¿¡¼­ Á¦´ë·Î stopÀÌ ¾ÈµÇ¾úÀ» ¼öµµ ÀÖÀ¸¹Ç·Î ¿©±â¼­ PsiMonitor´Â
2628        // cancelÀ» ÇØÁÖ¾î¾ß ÇÑ´Ù.
2629        //
2630        doDmc_CancelMonitors();
2631       
2632        Dmc_UnlockAVMutex();
2633}
2634
2635
2636// cafrii 060630, add video cache function
2637//
2638STATUS doDmc_StartDigital(UINT16 uVidPID, UINT16 uAudPID, UINT16 uPcrPID, 
2639                                                        DMC_VIDEO_CACHE vcache, tDHL_VideoCodingType vtype, tDHL_AudioCodingType atype)
2640{
2641        // video pid, pcr pid·Î ºñµð¿À µðÄÚµùÀ», audio pid¸¦ ÀÌ¿ëÇÏ¿© ¿Àµð¿À µðÄÚµùÀ» °³½ÃÇÑ´Ù.
2642        // ÀÌ Àü¿¡ ÀÌ¹Ì Demux_tsdStart() µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
2643        //
2644        // context´Â »õ·Î »ý¼ºµÈ´Ù.
2645        // ¸¸¾à flatten µÈ Á¤º¸°¡ ÀÖ´Ù¸é ±×°ÍÀ» restore ½ÃÄÑ »ç¿ëÇÑ´Ù.
2646        // ¿¡·¯°¡ ³ª¸é ¹Ù·Î ¸®ÅÏÇÑ´Ù. (timeout errorÀÎ °æ¿ì¿¡µµ ¸®ÅÏÇÔ.)
2647        //
2648
2649        AudioDecodeStartParam adsp;
2650
2651        DHL_RESULT dhlResult;   
2652
2653        BOOL bVideoFormatChanged = FALSE;
2654        BOOL bVideoStarted = FALSE;
2655       
2656        if (!Dmc_IsDmcTask()) {
2657                dprint(0, "!! doDmc_StartDigital() should be called only in DmcTask.\n");
2658                return statusInvalidState;
2659        }
2660
2661        if (uPcrPID == 0 ||
2662                (uVidPID == 0 && uAudPID == 0)) {
2663                dprint(0, "!! doDmc_StartDigital(): PID error. pcr %d, video %d, audio %d\n",
2664                                uPcrPID, uVidPID, uAudPID);
2665
2666                return statusInvalidArgument;
2667        }
2668
2669        if (dmc_bRunWithoutVideo) {
2670                dprint(0, "skip video by flag\n");
2671                goto process_audio;
2672        }
2673       
2674        if (uVidPID == 0) {
2675                dprint(2, "\t null video pid. skip..\n");
2676
2677#if SUPPORT_DMW_VIDEO_CACHE
2678                if (vcache) {
2679                        DHL_AV_DeleteVideoCacheData((tDHL_VideoCacheHandle)vcache);
2680                        vcache = 0;
2681                }
2682#endif
2683                goto process_audio;
2684        }
2685
2686
2687        // ------- video route setting ------------
2688
2689        dhlResult = DHL_CAP_ChangeVideoSource(0, eDHL_CAP_DTV_TS0);
2690        if (dhlResult) {
2691                dprint(0, "!! DHL_CAP_ChangeVideoSource err\n");
2692                // do nothing.. just go!
2693                dhlResult = DHL_OK;
2694        }
2695       
2696        // ------- process video ------------
2697
2698#if USE_PERF_MON
2699        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_VIDEO_START, 0);
2700#endif
2701
2702        // do video temp-mute not to see initial noisy screen
2703        dmc_bRequestVideoHide |= DMC_VIDEO_HIDE_VIDEO_START;
2704        dprint(2, "apply video temp-mute.. flag 0x%x\n", dmc_bRequestVideoHide);
2705        dhlResult = DHL_AV_VideoHide(0, TRUE);
2706        if (dhlResult)
2707                dprint(0, "!! temp video hide err 0x%x\n", dhlResult);
2708       
2709
2710#if SUPPORT_DMW_VIDEO_CACHE
2711        if (vcache)   // video cache Á¤º¸°¡ ÀÖÀ¸¸é ±×°ÍÀ¸·Î ¸ÕÀú ½Ãµµ..
2712        {
2713                dprint(2, "\tvideo start using vcache..\n");
2714                dhlResult = DHL_AV_StartCachedVideo(vcache);
2715                if (dhlResult) 
2716                {
2717                        dprint(0, "!! video vcache invalid? ignored!\n");
2718                        DHL_AV_DeleteVideoCacheData(vcache);
2719                        vcache = (DMC_VIDEO_CACHE)NULL;
2720                }
2721        }
2722#endif
2723       
2724        if (vcache == (DMC_VIDEO_CACHE)NULL) {
2725                dprint(2, "\t video normal start, v 0x%x, p 0x%x a 0x%x, vt %d\n", 
2726                                uVidPID, uPcrPID, uAudPID, vtype);
2727
2728                dhlResult = DHL_AV_VideoStart(0, uVidPID, uPcrPID, vtype);
2729        }
2730
2731#if 1 // for new hal architecture, new approach..
2732        // °ú°Å¿¡´Â DHL_AV_VideoStart() api ¾È¿¡ cancel_check ÇÔ¼ö°¡ °Ç³×Áö°í
2733        // Á¦´ë·Î µÈ video decoding ÀÌ È®ÀÎ µÉ ¶§ ±îÁö blocking µÇ´Â ¹æ½ÄÀ̾úÀ½.
2734        // neo hal ¿¡¼­ºÎÅÍ api°¡ º¯°æµÇ¾ú´Âµ¥, mw ÂÊ¿¡´Â ¹Ý¿µÀÌ ¾ÈµÇ°í ÀÖÀ½.
2735        // arc °ü·Ã ¹®Á¦ ÇØ°áÀ» À§Çؼ­´Â seq hdr Á¤º¸°¡ ÇʼöÀ̹ǷÎ
2736        // ¿©±â¼­ waiting À» ÇÒ ¼ö ÀÖÀ½. (doDmc_CheckCancel() polling Çϸ鼭..)
2737        // ±×·¯³ª ÀÌ ¹æ¹ýÀº audio start°¡ ´Ê¾îÁø´Ù´Â ´ÜÁ¡ÀÌ ÀÖ´Ù.
2738        //
2739        // ÀÌ¿¡ ´ëÇÑ ¶Ç ´Ù¸¥ ¹æ¾ÈÀº ¿©±â¼­´Â ±×³É ÁøÇà Çϰí audio start¸¦ Çϸç,
2740        // ³ªÁß¿¡ seq hdr change callbackÀÌ ºÒ¸®¸é ±× ¶§ arc Àû¿ëÀ» ÇÏ´Â °ÍÀÌ´Ù.
2741        // ±×·¯¸é ¾Æ·¡¿¡ formatchange Á¤º¸´Â ´çºÐ°£Àº ¾ûÅ͸®°¡ µÉ ¼ö ÀÖ´Ù.
2742#endif
2743       
2744        if (dhlResult) 
2745        {
2746                dprint(0, "!! DHL_AV_VideoStart err 0x%x\n", dhlResult);
2747
2748                // cafrii 050723 add
2749                // ¸¸¾à video context »ý¼ºÀÌ scrambledError°¡ ¾Æ´Ñ ´Ù¸¥ ¿¡·¯°¡ ¹ß»ýÇß´Ù¸é
2750                // video´Â ±×³É µÎ°í audio·Î °è¼Ó ÁøÇàÇÑ´Ù.
2751               
2752                if (dhlResult == DHL_WARN_SCRAMBLED) {
2753                        // audio µµ Ʋ¸²¾øÀÌ scramble µÇ¾ú´Ù°í °¡Á¤ÇÏ°í ±×³É Á¾·áÇÑ´Ù.
2754
2755                        // cafrii 060711 change
2756                        // video scramble ÀÌ´õ¶óµµ audio ÁøÇàÇϵµ·Ï ÇÑ´Ù.
2757                        // ¶ÇÇÑ air channelÀÇ °æ¿ì video scrambleÀº À߸øµÈ °ÍÀ̹ǷΠinvalid PES¿Í ´Ù¸¦ ¹Ù ¾ø´Ù.
2758                        //return statusScrambled;
2759                }
2760                if (dhlResult == DHL_FAIL_CANCELLED_BY_USER) {
2761                        return statusCancelled; 
2762                }
2763               
2764                if (dhlResult) {
2765                        //return err;
2766                       
2767                        // audio pid°¡ 0ÀÌ¸é ¿¡·¯¸¦ ¸®ÅÏÇØ¾ß ÇÑ´Ù.
2768                        if (uAudPID == 0) {
2769                                dprint(0, "!! video only program, but video invalid.\n");
2770                                return statusVideoError;
2771                        }
2772
2773                        bVideoStarted = FALSE; 
2774                                // uVidPID´Â validÇÏÁö¸¸ ¹®Á¦°¡ À־ video µðÄÚµù ½ÇÆÐ..
2775                        goto process_audio;
2776                }
2777        }
2778
2779        bVideoStarted = TRUE;
2780               
2781        dprint(2, "\tDHL_AV_VideoStart OK\n");
2782
2783
2784#if DMC_DELAYED_VIDEO_SHOW
2785        // ±×³É ¿©±â¼­´Â ±âÁ¸ seq hdr Á¤º¸¸¸ reset À» Çϰí
2786        // ³ªÁß¿¡ seq hdr change callback ÀÌ ¿À¸é ±× ¶§ ARC Àû¿ë ¹× temp blank unhide¸¦ ÇÑ´Ù.
2787        {
2788                ProgramAVInfo *av = Dmc_LockAVMutex();
2789                av->seq_hdr_valid = FALSE;
2790                Dmc_UnlockAVMutex();
2791        }
2792
2793#else
2794
2795        bVideoFormatChanged = FALSE;
2796       
2797        // °¡Àå ¸¶Áö¸·¿¡ ÀúÀåµÈ Sequence Header¿Í ÇöÀç seq¿Í ºñ±³Çؼ­
2798        // º¯°æµÈ »çÇ×ÀÌ ÀÖÀ» °æ¿ì¿¡¸¸ Àû¿ëÇÑ´Ù.
2799        //
2800        bVideoFormatChanged = doDmc_CheckIfFormatChanged();
2801       
2802        // Note!
2803        // ÃÖÃÊ Tuning½Ã¿¡´Â dmc_SeqHdrÀÇ °ªµéÀÌ ¸ðµÎ 0ÀÏ °ÍÀ̹ǷÎ
2804        // óÀ½ 1ȸ format change´Â ²À ºÒ¸®°Ô µÈ´Ù. (¼³·É ÇöÀç timingÀÌ ÀûÀýÇÑ °ÍÀ̶óÇØµµ..)
2805        // ÀÌ¹Ì ¼³Á¤ÇØ µÐ timing°ú ºñ±³ÇØ ºÁ¼­ º¯°æÇÒ Çʿ䰡 ¾øÀ» ¼öµµ Àִµ¥,
2806        // À̶§´Â application¿¡¼­ Dmc_InitDisplay¿¡¼­ ¼³Á¤ÇÑ °ª°ú ºñ±³Çؼ­
2807        // skip ÇÏ°Ô ÇÒ ¼öµµ ÀÖÀ» °ÍÀÌ´Ù.
2808        // MW´Â ¹«Á¶°Ç notify¸¦ ÇØÁØ´Ù.
2809               
2810        if (bVideoFormatChanged == FALSE)
2811                dprint(2, "\t  source format not changed\n");
2812        else
2813                dprint(2, "\t  source format changed\n");
2814               
2815        // »ç¿ëÀÚ ¼³Á¤°ªÀÌ ÀÖ´Â °æ¿ì, Adjustment, Sidebar, WinRect µîÀ» ¹Ì¸® ¼³Á¤Çسõ´Â´Ù.
2816        // ³ªÁß¿¡ Display startÇÒ ¶§ Àû¿ëµÇµµ·Ï..
2817        //
2818
2819        if (bVideoFormatChanged)
2820                doDmc_ProcessScreenAdjustment();
2821
2822#if 0 // NEW_DHL_API   
2823        dhlResult = DHL_AV_DispStart(NULL);
2824        if (dhlResult)
2825                dprint(0, "!! DHL_AV_DispStart err 0x%x\n", dhlResult);
2826#endif
2827
2828#if 0 // hide Ǫ´Â ½ÃÁ¡Àº µÚ¿¡..
2829        if (dmc_bRequestVideoHide) {
2830                DHL_AV_VideoHide(0, TRUE);
2831        }
2832        else { // show
2833                // ÀÌ ºÎºÐÀÇ Äڵ带 ½ÇÇàÇÏ¸é ºñµð¿À°¡ ±úÁö´Â ¹®Á¦ ¹ß»ý.
2834                // todo
2835                // video stop½Ã¿¡ hide µÈ °ÍÀ̶ó¸é Ç®¾îÁÖÁö ¾Ê¾Æ¼­ ¹®Á¦°¡ »ý±âÁö ¾Ê´Â°¡?
2836                // ±×·² °æ¿ì DHL¿¡¼­ °ü¸®ÇØÁà¾ß ÇÔ.
2837#if 0
2838                DHL_AV_VideoHide(FALSE);
2839#endif
2840        }
2841#endif
2842
2843#endif // DMC_DELAYED_VIDEO_SHOW
2844
2845
2846        if (1) {
2847                ProgramAVInfo *av = Dmc_LockAVMutex();
2848                av->video_hidden = (dmc_bRequestVideoHide & DMC_VIDEO_HIDE_USER) ? TRUE : FALSE;
2849                Dmc_UnlockAVMutex();
2850        }
2851       
2852
2853#if USE_PERF_MON
2854        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_VIDEO_START, 1);
2855#endif
2856
2857       
2858process_audio:
2859
2860        if (uAudPID == 0) {
2861                dprint(2, "\t null audio pid. skip..\n");
2862                goto label_end;
2863        }
2864       
2865        if (dmc_bRunWithoutAudio) {
2866                dprint(0, "skip audio by flag.\n");
2867                goto label_end;
2868        }
2869
2870        dhlResult = DHL_CAP_ChangeAudioSource(eDHL_CAP_DTV_TS0_AUDIO);
2871        if (dhlResult) {
2872                dprint(0, "!! DHL_CAP_ChangeAudioSource err\n");
2873                // do nothing.. just go!
2874                dhlResult = DHL_OK;
2875        }
2876
2877#if USE_PERF_MON
2878        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AUDIO_START, 0);
2879#endif
2880
2881        // ------- audio route setting ------------
2882
2883        dhlResult = DHL_CAP_ChangeAudioSource(eDHL_CAP_DTV_TS0_AUDIO);
2884        if (dhlResult) {
2885                dprint(0, "!! DHL_CAP_ChangeAudioSource err\n");
2886                // do nothing.. just go!
2887                dhlResult = DHL_OK;
2888        }
2889
2890        // ------- audio processing ------------
2891
2892        dmc_bWaitFirstFreezeVideoEndEvent = TRUE;
2893       
2894        // 030918 cafrii
2895        // audio¸¦ ¼¼ÆÃÇÏ´Â ¼ø°£ pop noise°¡ ¹ß»ýÇÒ ¼ö À־
2896        // º¸Åë Audio ½ÃÀÛ Àü¿¡ mute¸¦ ÇÑ´Ù.
2897        // mute¸¦ offÇÏ´Â ½ÃÁ¡Àº video°¡ ³ª¿À±â ½ÃÀÛÇÏ´Â ½ÃÁ¡ÀÌ
2898        // Àû´çÇϹǷΠÀÌ ¼ø°£¿¡ freeze video end¸¦ ±â´Ù¸®´Â flag¸¦ Ãß°¡ÇÑ´Ù.
2899        //
2900        // freeze_end °¡ ³Ê¹« »¡¸® ³ª¿Í¹ö·È´Ù¸é ¾ÕÀ¸·Î ¿µ¿øÈ÷ audio°¡ ³ª¿ÀÁö ¾Ê´Â ¹®Á¦°¡ »ý±æ¼ö°¡ Àִµ¥,
2901        // ¾ÆÁ÷ Àû´çÇÑ ÇØ°á ¹æ¹ýÀº ¾ø´Ù.
2902        // --> freeze_end °¡ ¾Æ¹«¸® »¡¸® ³ª¿À´õ¶óµµ DMC task¿¡¼­ freeze end¸¦ ó¸®ÇϹǷÎ
2903        //     ÀÌ ÇÔ¼ö°¡ ³¡³ª±â Àü±îÁö´Â freeze end°¡ 󸮵ÇÁö ¾Ê´Â´Ù. ¹®Á¦ ¾øÀ½.
2904        //
2905        // ¶ÇÇÑ Audio only channelÀÌ ÀÖÀ»¼ö ÀÖÀ¸¹Ç·Î video°¡ ¾øÀ» °æ¿ì¿¡´Â audio mute¸¦
2906        // ¹Ù·Î ²¨¾ß¸¸ ÇÑ´Ù.
2907
2908        memset(&adsp, 0, sizeof(AudioDecodeStartParam));
2909       
2910        adsp.result = statusNotImpl;  // my default.
2911        adsp.audPid = uAudPID;
2912        adsp.pcrPid = uPcrPID;
2913        adsp.audType = atype;
2914        //adsp.mode = MOCHA_ATSC_INPUT; // cafrii 031117 add
2915
2916        doDmc_Notify(DMW_NOTIFY_AudioDecodeStart, (UINT32) &adsp);
2917       
2918        if (adsp.result == statusNotImpl) 
2919        {
2920                tDHL_AudioCodingType dhlAudType;
2921
2922                if (dmc_bAudioVideoSyncStart) {
2923                        dprint(2, "\tAudio muted for sync start\n");
2924                        doDmc_AudioTempMute(TRUE);
2925                        DMW_SYS_SetTimer(TIMER_ID_AUDIO_TEMPMUTE_LIMIT, g_AudioTempMuteLimitMs, 
2926                                doDmc_AudioTempMuteLimitTimerProc, 0, TRUE);
2927                }
2928#if 0
2929                // todo
2930                // ÇöÀç DD HAL¿¡¼­ Áö¿øÇÏ´Â audio typeÀÌ ¸î°³ ¾ÈµÈ´Ù.
2931                // driver¿¡¼­´Â tDHL_AudioCodingType Á¾·ù°¡ »ó´çÈ÷ ¸¹´Ù. (¹°·Ð ¸ðµÎ ´Ù Áö¿øÇϴ°ÍÀº ¾Æ´Ô)
2932                //
2933                // arzhna, 100315
2934                // audio type°ú stream typeÀ» ±¸ºÐÇØ¾ßÇÔ,
2935                // DHL_AV_AudioStart ¿¡¼­ ÇÊ¿äÇÑ ÀÎÀÚ´Â audiotype
2936                #define eDHL_AUDIO_TYPE_2_DHLAUDIOTYPE(a) ( \
2937                                (a) == eDHL_AUDIO_TYPE_AC3 ? eDHL_AUDIO_TYPE_AC3 : \
2938                                (a) == eDHL_AUDIO_TYPE_MPEG_1 ? eDHL_AUDIO_TYPE_MPEG_1 : \
2939                                (a) == eDHL_AUDIO_TYPE_MPEG_2 ? eDHL_AUDIO_TYPE_MPEG_2 : \
2940                                (a) == eDHL_AUDIO_TYPE_AAC ? eDHL_AUDIO_TYPE_AAC : \
2941                                                        eDHL_AUDIO_TYPE_AC3)
2942
2943                // cafrii 070718, use 'atype' argument
2944                dhlAudType = eDHL_AUDIO_TYPE_2_DHLAUDIOTYPE(atype);
2945#else
2946                dhlAudType = atype;
2947#endif
2948
2949                dprint(2, "\t audio start, a 0x%x p 0x%x, at %d\n", uAudPID, uPcrPID, dhlAudType);
2950
2951
2952#if 1 // NEW_DHL_API
2953                dhlResult = DHL_AV_AudioStart(uAudPID, uPcrPID, dhlAudType);
2954                if (dhlResult)
2955                        dprint(0, "!! audio start err 0x%x\n", dhlResult);
2956
2957#else
2958                // cafrii 060711 add audio start check
2959
2960                if (dmc_bUseAudioStartWait == 0)
2961                        dhlResult = DHL_AV_AudioStart(uAudPID, uPcrPID,
2962                                                                                 dhlAudType);
2963                else
2964                {
2965                        dhlResult = DHL_AV_AudioStartWait(uAudPID, uPcrPID, 
2966                                                dhlAudType, doDmc_CheckCancel);
2967
2968                        // cafrii 060808 add, bugfix!
2969                        if (dhlResult == DHL_FAIL_CANCELLED_BY_USER) {
2970                                if (bVideoStarted) {
2971#if 0 // NEW_DHL_API
2972                                        DHL_AV_DispStop();
2973#endif
2974                                        // zooyouny 100629 : tDHL_VDID´Â ÀÏ´Ü 0À¸·Î ó¸®, ¹®Á¦ µÉ ¼ö ÀÖÀ½
2975                                        DHL_AV_VideoStop(0);
2976                                }
2977                                return statusCancelled;
2978                        }
2979                       
2980                        if (dhlResult) {
2981                                dprint(0, "!! audio start err 0x%x\n", dhlResult);
2982
2983                                // video ¸¶Àú ¾ø´Ù¸é ÀÌ´Â ¿¡·¯ÀÌ´Ù.
2984                                if (bVideoStarted == FALSE)
2985                                        return statusError;
2986                        }
2987                }
2988#endif
2989
2990                // tDHL_AudioCodingType °ú DHL_AUD_STREAMTYPE ±¸ºÐ..
2991
2992                if (dmc_bAudioVideoSyncStart) {
2993                        // sync start¸¦ À§Çؼ­´Â ¿©±â¼­ unmute¸¦ ÇÏÁö ¾Ê°í
2994                        // video first freeze end°¡ ¿ÔÀ»¶§ Ç®¾îÁÖµµ·Ï ÇÑ´Ù.
2995                        //
2996                        if (bVideoStarted) {
2997                                dprint(2, "\tAV SyncStart mode.. AudioTmpMute off deferred later..\n");                                         
2998                        }
2999                        else {
3000                                dprint(2, "\tAV SyncStart mode, but no video.. Clear AudioTmpMute..\n");
3001                                dmc_bWaitFirstFreezeVideoEndEvent = FALSE; 
3002                                        // ¿©±â¼­ ¹Ù·Î ó¸®ÇϹǷΠwaitÇÏÁö ¾Ê´Â´Ù.
3003                                doDmc_AudioTempMute(FALSE);
3004                        }
3005                }
3006
3007        }
3008        else if (adsp.result == statusOK) 
3009        {
3010
3011        }
3012        else 
3013        {
3014                dprint(0, "!! AudioDecodeStart err %d\n", adsp.result);
3015                if (bVideoStarted == FALSE)
3016                        return adsp.result;
3017        }
3018
3019#if USE_PERF_MON
3020        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AUDIO_START, 1);
3021#endif
3022       
3023
3024label_end:
3025
3026        // ÇöÀç ÀÌ ÇÔ¼ö¿¡¼­´Â program number¸¦ ¾Ë ¼ö ¾ø´Ù.
3027        // 1394 Áö¿øÇÏÁö ¾ÊÀ½.
3028        //if (_Dmc_DecodeStartCallback)
3029        //      _Dmc_DecodeStartCallback(dmc_program->program_number, FALSE);
3030       
3031        return statusOK;
3032}
3033
3034
3035STATUS doDmc_StartAnalog(CaptureParam *pCapParam) 
3036{
3037        // Analog Video context¸¦ »ý¼ºÇÏ°í °ü·ÃµÈ audio¸¦ ó¸®ÇÑ´Ù.
3038        // TS°¡ ¾Æ´Ñ uncompressed video(656 format)Àº ¸ðµÎ analog video context·Î 󸮵ȴÙ.
3039        // NTSC, External Video, DV µîÀÌ ¸ðµÎ ÀÌ °æ¿ì¿¡ ÇØ´çÇÑ´Ù.
3040       
3041        DHL_RESULT dhlResult;
3042        AudioDecodeStartParam adsp;
3043        ProgramAVInfo *av;
3044        STATUS status = statusOK;
3045       
3046        if (!Dmc_IsDmcTask()) {
3047                dprint(0, "!! doDmc_StartAnalog() should be called only in DmcTask.\n");
3048       
3049                return statusInvalidState;
3050        }
3051       
3052        av = Dmc_LockAVMutex();
3053       
3054        if (av->active) {
3055                // ±âº» ¹æÄ§À» StartDigital, StartAnalog Çϱâ Àü¿¡ caller¿¡¼­
3056                // ÀÌÀü video¸¦ stop ½ÃŰ´Â °ÍÀ¸·Î Á¤ÇÔ.
3057                //
3058                dprint(1, "!! Warning! stop video before tuning new channel!\n");
3059                doDmc_Stop(); // no delete task
3060        }
3061
3062        // cafrii 070413 add
3063        //  audio¸¸ capture ½ÃÀÛÇϴ Ư¼ö ¸ðµå Áö¿ø.
3064        if (pCapParam->input_video == eDHL_CAP_VIDEO_NONE) {
3065                dprint(2, "  audio capture only\n");
3066                goto label_audio;
3067        }
3068               
3069        // ------- process video ------------
3070       
3071#if USE_PERF_MON
3072        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_VIDEO_START, 0);
3073#endif
3074
3075        dhlResult = DHL_CAP_ChangeVideoSource(0, pCapParam->input_video);
3076        if (dhlResult)
3077                dprint(0, "!! DHL_CAP_ChangeVideoSource err 0x%x\n", dhlResult);
3078       
3079        dhlResult = DHL_CAP_VideoStart(0);
3080        if (dhlResult) {
3081                dprint(0, "!! DHL_CAP_VideoStart err 0x%x\n", dhlResult);
3082                status = statusVideoError;
3083                goto label_end;  // cafrii 060714 bugfix!
3084        }
3085
3086//      bVideoFormatChanged = doDmc_CheckIfFormatChanged();
3087
3088        // cafrii 060609 add
3089        doDmc_ProcessScreenAdjustment();
3090       
3091        dhlResult = DHL_CAP_DispStart();
3092        if (dhlResult) {
3093                dprint(0, "!! DHL_CAP_DispStart err 0x%x\n", dhlResult);
3094                status = statusVideoError;
3095                goto label_end; // cafrii 060714 bugfix!
3096        }
3097
3098        if (dmc_bRequestVideoHide) {
3099                DHL_AV_VideoHide(0, TRUE);
3100        }
3101        else { // show
3102                DHL_AV_VideoHide(0, FALSE);
3103        }
3104
3105        av->video_hidden = dmc_bRequestVideoHide ? TRUE : FALSE;
3106
3107#if USE_PERF_MON
3108        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_VIDEO_START, 1);
3109#endif
3110
3111
3112        // ------- process audio ------------
3113
3114label_audio:
3115
3116#if USE_PERF_MON
3117        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AUDIO_START, 0);
3118#endif
3119
3120        dhlResult = DHL_CAP_ChangeAudioSource(pCapParam->input_audio);
3121        if (dhlResult)
3122                dprint(0, "!! DHL_CAP_ChangeAudioSource err 0x%x\n", dhlResult);
3123               
3124        if (dmc_bRunWithoutAudio == 0) 
3125        {
3126                // Âü°í·Î AnalogÀÇ °æ¿ì¿¡´Â AVSyncStart´Â Áö¿øÇÏÁö ¾Ê´Â´Ù.
3127                //
3128                //dmc_bWaitFirstFreezeVideoEndEvent = FALSE; // do not wait FreezeVideoEnd event.
3129               
3130                // cafrii 070102, analogµµ freeze end event ÇÊ¿äÇÔ.
3131                dmc_bWaitFirstFreezeVideoEndEvent = TRUE;
3132               
3133                memset(&adsp, 0, sizeof(AudioDecodeStartParam));
3134                adsp.result = statusNotImpl;  // my default.
3135                //adsp.mode = MOCHA_NTSC_INPUT;
3136                 
3137                doDmc_Notify(DMW_NOTIFY_AudioDecodeStart, (UINT32) &adsp);
3138               
3139                if (adsp.result == statusNotImpl) {
3140                        dhlResult = DHL_CAP_AudioStart();
3141                        if (dhlResult)
3142                                dprint(0, "!! DHL_CAP_AudioStart err 0x%x\n", dhlResult);
3143                }
3144                else if (adsp.result == statusOK) {
3145                       
3146                }
3147                else {
3148                        dprint(0, "!! AudioDecodeStart err %d\n", adsp.result);
3149                        return adsp.result;  // Àüü Æ©´× ¿¡·¯·Î ¸®ÅÏÇÑ´Ù. ÁÖÀÇ!!
3150                }
3151        }
3152       
3153#if USE_PERF_MON
3154        DHL_PerfMonCheck(gDmcPMTune, PM_EV_TUNE_AUDIO_START, 1);
3155#endif
3156
3157label_end:
3158        Dmc_UnlockAVMutex();
3159       
3160        return status;
3161}
3162
3163
3164#if COMMENT
3165_______________(){}
3166#endif
3167
3168
3169#if 0
3170DMC_VIDEO_CACHE doDmc_LoadVideoCache(int rf, int program_number, int video_pid, int pcr_pid)
3171{
3172        DMC_VIDEO_CACHE cache;
3173        cache = DHL_AV_LoadVideoFromCache(rf, program_number, video_pid, pcr_pid);
3174
3175        return cache;
3176}
3177
3178doDmc_SaveVideoCache()
3179{
3180
3181}
3182
3183#endif
3184
3185
3186#if COMMENT
3187_______________(){}
3188#endif
3189
3190
3191#if !USE_EPG_MW_PSI_DOWNLOAD
3192
3193//-----------------------------------------------------------
3194// PSI Monitor Control °ü¸®
3195
3196// ä³Î Æ©´×ÀÌ ³¡³ª¸é DMC´Â PSI ¸ð´ÏÅ͸¦ °¡µ¿½ÃÄѼ­ PSI Change¿¡ ´ëºñÇϰԲû ÇÑ´Ù.
3197// À̰Ͷ§¹®¿¡ ´Ù¸¥ °÷¿¡¼­ PSI TableÀ» ¹ÞÀ¸·Á°í ÇØµµ timeout ¿¡·¯°¡ ¹ß»ýÇÑ´Ù.
3198//
3199// ÀÌ¿¡ ´ëÇÑ ÇØ°áÃ¥À¸·Î´Â
3200//  (1) TableÀ» »õ·Î ¹Þ´Â ´ë½Å DMC°¡ °ü¸®Çϰí ÀÖ´Â PSI tableÀ» lock »óÅ¿¡¼­ ÀÌ¿ëÇϰųª,
3201//  (2) Psi monitor¸¦ ÀϽà ÁßÁö½ÃÄѳõ°í ´Ù¿î·Îµå ÇÑ´ÙÀ½ ´Ù½Ã resume½ÃŰ´Â ¹æ¹ýÀ» »ç¿ëÇÑ´Ù.
3202//
3203
3204STATUS Dmc_PausePsiMonitor(UINT32 bPause)
3205{
3206        DHL_RESULT err = DHL_OK;
3207        ProgramAVInfo *av;
3208       
3209        if (!Dmc_IsDmcTask()) 
3210        {
3211                dprint(2, "Dmc_PausePsiMonitor(%d)\n", bPause);
3212       
3213                return Dmc_EnqueueDPC((DMC_FN_DPC)Dmc_PausePsiMonitor, bPause, 0, 0, 0, TRUE);
3214        }
3215
3216        dprint(1, "cmdPausePsiMonitor(%d):\n", bPause); 
3217       
3218        av = Dmc_LockAVMutex();
3219       
3220        if (bPause) // Pause
3221        {
3222#if USE_CH_MW_ALL_PMT_DOWNLOAD
3223                dprint(2, "\t pause current PsiCtl monitor (pat 0x%08x pmt1 0x%08x pmt2 0x%08x)..\n", 
3224                                                av->patPsiCtl, av->pmtPsiCtl, av->pmtPsiCtl2);
3225#else
3226                dprint(2, "\tPause current PsiCtl monitor (pat 0x%08x, pmt 0x%08x)..\n", 
3227                                                av->patPsiCtl, av->pmtPsiCtl);
3228#endif
3229
3230#if USE_CH_MW_ALL_PMT_DOWNLOAD
3231                DHL_PSI_StopMonitor(av->pmtPsiCtl2);
3232                av->pmtPsiCtl2 = (tDHL_PSI_ControlHandle)0;
3233#endif
3234               
3235                DHL_PSI_StopMonitor(av->pmtPsiCtl);
3236                av->pmtPsiCtl = (tDHL_PSI_ControlHandle)0;
3237               
3238                DHL_PSI_StopMonitor(av->patPsiCtl);
3239                av->patPsiCtl = (tDHL_PSI_ControlHandle)0;
3240               
3241                // Queue¿¡ ³²¾ÆÀÖ´Â PAT/PMT Change event´Â ºñ¿ö¾ß Çϴ°¡?
3242                // --> ³ªÁß¿¡ pat/pmt handler¿¡¼­ PsiCtlÀÌ NULLÀÎÁö¸¦ üũ¸¦ Çϱ⠶§¹®¿¡
3243                //     ±×·² ÇÊ¿ä´Â ¾ø´Ù.
3244        }
3245        else
3246        {
3247                // ÇöÀç ¸ð´ÏÅ͸µÀÌ °¡µ¿ÁßÀÌ¸é ¾Æ¹«Àϵµ ÇÏÁö ¾Ê´Â´Ù.
3248               
3249                if (av->patPsiCtl == 0) {
3250                        dprint(2, "\tPAT monitor resume..\n");
3251       
3252                        if (av->pat == NULL || av->pmt == NULL) {
3253                                dprint(2, " Psi Not prepared (pat %x, pmt %x).. wait first pmt..\n", av->pat, av->pmt);
3254                        }
3255                       
3256                        err = MonitorPAT(Dmc_GetCurrentTsd(),
3257                                        TRUE, // Ç×»ó current PAT¸¸ ¹Þ´Â´Ù!!
3258                                        FALSE, // not eager
3259                                        dmc_PatUpdateMode,
3260                                        _Dmc_PatEventProc, 0,
3261                                        &av->patPsiCtl);
3262       
3263                        if (err)
3264                                dprint(0, "!! MonitorPAT returned %s\n", ErrorString(err));
3265                }
3266       
3267                // PMT Monitor´Â PAT°¡ ¼ö½ÅµÈ ÀÌÈÄ¿¡, ±× ½ÃÁ¡¿¡¼­ µ¿ÀÛÁßÀÎ VideoÀÇ program number¸¦
3268                // ÀÌ¿ëÇØ PMT¸¦ ¼±ÅÃÇÑ ´ÙÀ½ ½ÃÀÛÇÑ´Ù.   
3269        }
3270
3271        Dmc_UnlockAVMutex();
3272               
3273        return err ? statusError : statusOK;
3274}
3275
3276#endif // !USE_EPG_MW_PSI_DOWNLOAD
3277
3278STATUS Dmc_InitAVResources(void)
3279{
3280       
3281        dmc_psiSema4 = DHL_OS_CreateMutexSemaphore("DmcPsi");
3282        if (dmc_psiSema4 == 0) {
3283                dprint(0, "!! create psi sema4 failed");
3284                return statusOutOfResource;
3285        }
3286       
3287        dmc_avSema4 = DHL_OS_CreateMutexSemaphore("DmcAV");
3288        if (dmc_avSema4 == 0) {
3289                dprint(0, "!! create av sema4 failed");
3290                return statusOutOfResource;
3291        }
3292
3293        DHL_AV_SetCallback(eDHL_CB_VideoSeqHdr, _Dmc_CommonAVCallback);
3294        DHL_AV_SetCallback(eDHL_CB_FirstVideoShow, _Dmc_CommonAVCallback);
3295
3296        return statusOK;
3297}
3298
3299
3300// Dmc_RegisterDecodeStartCallback
3301//    Decode start callback Çڵ鷯¸¦ µî·Ï/ÇØÁ¦ÇÑ´Ù.
3302//    µðÄÚµùÀÌ ½ÃÀÛµÉ ¶§ (StartDigital ÀÌÈÄ) ¸¶´Ù ÀÌ Çڵ鷯°¡ È£ÃâµÈ´Ù.
3303//    ÁÖ·Î Partial stream Ãâ·ÂÀ» À§Çؼ­ »ç¿ëµÈ´Ù.
3304//    ÀÌÀü¿¡ µî·ÏµÇ¾î ÀÖ´Â handler°¡ ¸®ÅϵǹǷΠcallback chainingÀ» ÇÒ¼ö ÀÖ´Ù.
3305//
3306DMC_FN_NOTIFY Dmc_RegisterDecodeStartCallback(DMC_FN_NOTIFY callback)
3307{
3308        // return previously registerred callback pointers.
3309        // so that notification chaining is possible.
3310
3311        DMC_FN_NOTIFY fnPrevCallback;
3312       
3313        fnPrevCallback = _Dmc_DecodeStartCallback;
3314        _Dmc_DecodeStartCallback = callback;
3315        if (callback)
3316                dprint(1, "DecodeStart callback %x registerred\n", callback);
3317        else
3318                dprint(1, "DecodeStart callback unregistered\n");
3319
3320        return fnPrevCallback;
3321}
3322
3323// Dmc_RegisterDecodeStopCallback
3324//    Decode stop callback Çڵ鷯¸¦ µî·Ï/ÇØÁ¦ÇÑ´Ù.
3325//    µðÄÚµùÀÌ ³¡³¯ ¶§ È£ÃâµÈ´Ù.
3326//
3327DMC_FN_NOTIFY Dmc_RegisterDecodeStopCallback(DMC_FN_NOTIFY callback)
3328{
3329        // return previously registerred callback pointers.
3330        // so that notification chaining is possible.
3331
3332        DMC_FN_NOTIFY fnPrevCallback;
3333       
3334        fnPrevCallback = _Dmc_DecodeStopCallback;
3335        _Dmc_DecodeStopCallback = callback;
3336        if (callback)
3337                dprint(1, "DecodeStop callback %x registerred\n", callback);
3338        else
3339                dprint(1, "DecodeStop callback unregistered\n");
3340
3341        return fnPrevCallback;
3342}
3343
3344
3345
3346
3347// Dmc_RegisterNotificationCallback
3348//    Notification callbackÀ» µî·Ï/ÇØÁ¦ÇÑ´Ù.
3349//    DMC¿¡¼­ ÀϾ´Â ¿©·¯°¡Áö À¯¿ëÇÑ Á¤º¸¸¦ Notification À» ÅëÇØ¼­
3350//    ¾Ë·ÁÁֱ⠶§¹®¿¡ °¡´ÉÇϸé ÀÌ ±â´ÉÀ» »ç¿ëÇÏ´Â°Ô ÁÁ´Ù.
3351//
3352
3353DMC_FN_NOTIFY Dmc_RegisterNotificationCallback(DMC_FN_NOTIFY callback)
3354{
3355        // return previously registerred callback pointers,
3356        // so that notification chaining is possible.
3357       
3358        DMC_FN_NOTIFY fnPrevCallback;
3359       
3360        fnPrevCallback = _Dmc_Notify;
3361        _Dmc_Notify = callback;
3362        if (callback)
3363                dprint(1, "Notification callback %x registerred.\n", callback);
3364        else
3365                dprint(1, "Notification callback unregistered.\n");
3366
3367        return fnPrevCallback;
3368}
3369
3370
3371/* neverdai 101019 add. autoscan ½Ã callbackÀ» ¹Þ¾Æ¼­ ºñµð¿À È­¸é¿¡ º¸ÀÌ´Â ¹®Á¦°¡ ÀÖÀ½
3372   scanÇÒ ¶§´Â callbackÀ» ¹ÞÁö ¾Êµµ·Ï º¯°æÇÏ´Â °ÍÀÌ ÁÁÀ» µíÇÔ.
3373*/
3374void DMC_RegisterVideoCallback(BOOL bset)
3375{
3376        if(bset) {
3377                DHL_AV_SetCallback(eDHL_CB_VideoSeqHdr, _Dmc_CommonAVCallback);
3378                DHL_AV_SetCallback(eDHL_CB_FirstVideoShow, _Dmc_CommonAVCallback);
3379        }
3380        else {
3381                DHL_AV_SetCallback(eDHL_CB_VideoSeqHdr, NULL);
3382                DHL_AV_SetCallback(eDHL_CB_FirstVideoShow, NULL);
3383        }
3384               
3385}
3386
3387
3388
3389
3390// cafrii 060724 add
3391void Dmc_PrintAVInfo(int level)
3392{
3393        ProgramAVInfo *av = Dmc_LockAVMutex();
3394
3395        dprint(level, "  active %d, analog %d, input video %d/audio %d\n",
3396                        av->active, av->analog, av->input_video, av->input_audio);
3397        dprint(level, "  rf %d, mod %d (%s), tune method %d (%s)\n",
3398                        av->rf, av->mod, ServiceTypeString(av->mod), 
3399                        av->method, TuneMethodString(av->method));
3400        dprint(level, "  major %d, minor %d, #%d, pid pva %x/%x/%x\n",
3401                        av->major, av->minor, av->program_number, 
3402                        av->pcr_pid, av->video_pid, av->audio_pid);
3403        dprint(level, "  freezed %d, hidden %d\n",
3404                        av->video_freezed, av->video_hidden);
3405        dprint(level, "  pat 0x%x, pmt 0x%x, psictl pat %x, pmt %x\n", 
3406                        av->pat, av->pmt, av->patPsiCtl, av->pmtPsiCtl);
3407
3408        // pmtlist Á¤º¸¸¦ º¸°í ½Í´Ù¸é Dmc_PrintProgramInfo ¸¦ »ç¿ëÇÒ °Í!!
3409        Dmc_UnlockAVMutex();
3410}
3411
3412
3413#if COMMENT
3414________(){}
3415#endif
3416
3417#if DMW_REGISTER_DEBUG_SYMBOL
3418
3419static DHL_SymbolTable symbols[] =
3420{
3421        //---- functions
3422        DHL_FNC_SYM_ENTRY(Dmc_PrintAVInfo),
3423       
3424        //---- vars
3425        DHL_VAR_SYM_ENTRY(dmc_bRunWithoutAudio),
3426        DHL_VAR_SYM_ENTRY(dmc_bRunWithoutVideo),
3427        DHL_VAR_SYM_ENTRY(dmc_bRequestVideoHide),
3428       
3429        DHL_VAR_SYM_ENTRY(g_Trace_bDmcPsiEvent),
3430
3431        //DHL_VAR_SYM_ENTRY(dmc_bUseAudioStartWait),
3432
3433};
3434
3435#endif
3436
3437void RegisterChannelAVSymbols(void)
3438{
3439       
3440#if DMW_REGISTER_DEBUG_SYMBOL
3441        DHL_DBG_RegisterSymbols(symbols, DHL_NUMSYMBOLS(symbols));
3442#endif
3443
3444}
3445
3446
Note: See TracBrowser for help on using the repository browser.