xref: /utopia/UTPA2-700.0.x/modules/dscmb/api/nsk2hdi/nsk2hdx_ecmflt.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 
2 #include <string.h>
3 #include "MsCommon.h"
4 
5 
6 #include "hdi_121.h"
7 #include "nsk_dbg.h"
8 #include "apiDMX.h"
9 #include "nsk2hdi_header.h"
10 
11 
12 /*****************************************************************************\
13   \Definitions
14 \*****************************************************************************/
15 #define MDL_ECMFLT_OK                   1
16 #define MDL_ECMFLT_FAIL                 2
17 #define MDL_ECMFLT_INVALID_REQUEST      3
18 #define ECMFLT_TASK_STACK_SIZE          16*1024
19 
20 #define ECMBufferSize       188
21 
22 #define ECMDMX_BufferSize   ECMBufferSize*100
23 
24 #define ECMPacketArrive         0x10000
25 #define ECMBufOverFlow          0x100000
26 
27 #define ECMRecvieBuf            10
28 
29 #define MaximumConnection       2
30 
31 #define MaximumDmxId            128
32 
33 #define ECMStopFlag             0xFF
34 
35 #define EcmTmpBufSize           10*1024
36 
37 
38 /*****************************************************************************\
39   \ local variables
40 \*****************************************************************************/
41 static MS_U8  _u8EcmFltIsInit = FALSE;
42 
43 static MS_S32 _s32ECMFLTMutexId = -1;
44 static MS_S32 _s32ECMFLTEventId = -1;
45 static MS_S32 _s32ECMDFLTTaskId = -1;
46 
47 static void*  _pECMDFLTTaskStack;
48 //static MS_U8  _u8ECMDFLT_StackBuffer[ECMFLT_TASK_STACK_SIZE];
49 
50 static MS_U16 Pids[MaximumDmxId];
51 static MS_U8  *ECMAllocBuf[MaximumDmxId];
52 static MS_U16 ECM_Connection[MaximumDmxId];
53 static MS_U8 ECMBufCnt[MaximumDmxId];
54 static MS_U8 *pECMBufBack[MaximumDmxId][ECMRecvieBuf];
55 static MS_U8 ECMFlags[MaximumDmxId][2];
56 
57 
58 //prepare larger buffer first...
59 static MS_U8  TmpBuf[EcmTmpBufSize];
60 static MS_U8  last_ecm_polarity[2] = {2,2};
61 
62 static MS_BOOL XConnFileInFlag[2] = {FALSE,FALSE};
63 static NDS_USHORT _gecm_pid[2] = {0x0,0x0};
64 
65 static MS_U32 _bEcm_log = FALSE;
66 
67 static NDS_UBYTE *plastECM;
68 
69 
70 /*****************************************************************************\
71   \ global variables
72 \*****************************************************************************/
73 
74 
75 /*****************************************************************************\
76   \ local functions
77 \*****************************************************************************/
data_dump(MS_U8 * pu8Buf,MS_U32 BufSize)78 void data_dump(MS_U8* pu8Buf, MS_U32 BufSize)
79 {
80     MS_U32 i ;
81 
82     for( i = 0 ; i < BufSize ; i ++ ){
83         if((i%16) == 0 ) printf("\n");
84         printf("%02X ",*(pu8Buf + i));
85     }
86 }
87 
_NSK2_ECMDFLT_Isr_Proc(void)88 static void _NSK2_ECMDFLT_Isr_Proc(void)
89 {
90 
91     MS_U32 u32Events;
92     MS_U8  DmxIdSect;
93     MS_U8* pu8Read;
94     MS_U8* pu8Write;
95     MS_U8  ecm_polarity;
96     MS_U8* pu8VARead;
97     MS_U32 DataLen, DataRmn;
98     MS_U8* pu8Ptr;
99     MS_U16 connection;
100 
101     while (1)
102     {
103         //NSK_TRACE(("ECMDFLT_Isr_Proc wait Event\n"));
104         MsOS_WaitEvent(_s32ECMFLTEventId, 0xFFFFFFFF /*ECMFLT_STATES_GROUP*/, &u32Events, E_OR_CLEAR, MSOS_WAIT_FOREVER /*1000*/ );
105 
106         //NSK_TRACE(("u32Event = %x\n",u32Events));
107         MsOS_ObtainMutex(_s32ECMFLTMutexId,MSOS_WAIT_FOREVER);
108 
109 
110         DmxIdSect = (u32Events & 0xff);
111         connection = ((u32Events>>8) & 0xff);
112         //NSK_TRACE(("DmxIdSect:%x, connection = %x\n",DmxIdSect,connection));
113 
114         if( ECMFlags[DmxIdSect][0] == ECMStopFlag )
115         {
116             NSK_TRACE(("ECM already stop\n"));
117             goto ProcEnd;
118         }
119 
120         // Get Buffer Read Pointer.
121         MApi_DMX_SectReadGet(DmxIdSect, (MS_PHY*)(&pu8Read));
122         //NSK_TRACE(("Read pointer = 0x%08lx\n", (MS_U32)pu8Read));
123 
124         // Get Buffer Write Pointer.
125         MApi_DMX_SectWriteGet(DmxIdSect, (MS_PHY*)(&pu8Write));
126         //NSK_TRACE(("Write pointer = 0x%08lx\n", (MS_U32)pu8Write));
127 
128 
129         if ((pu8Write- pu8Read) == 0 )
130         {
131             NSK_TRACE(("\n !! No Section Get - Wait timeout \n" ));
132         }
133         else
134         {
135             //NSK_TRACE(("bytes need to be readed = %x\n",((MS_U32)pu8Write- (MS_U32)pu8Read)));
136             //memcpy(_u8ECMBuf, (void *)MsOS_PA2KSEG1((MS_U32)pu8Read), 188);
137 
138         #if 1 // temp, Jeff
139             MsOS_ReadMemory();
140             //DMA_Api for user to Copy data from HW section Buffer into user data Buffer.
141             MApi_DMX_CopyData(DmxIdSect,TmpBuf,EcmTmpBufSize,&DataLen,&DataRmn,NULL);
142         #endif
143 
144             //NSK_TRACE(("copy data length = %x, data remain = %x\n",DataLen,DataRmn));
145 
146             if(DataRmn!=0)
147             {
148                 MApi_DMX_CopyData(DmxIdSect,&TmpBuf[DataLen],EcmTmpBufSize,&DataLen,&DataRmn,NULL);
149                 //NSK_TRACE(("2. copy data length = %x, data remain = %x\n",DataLen,DataRmn));
150             }
151 
152             pu8VARead = (MS_U8 *)TmpBuf;
153 
154             //NSK_TRACE(("first six bytes are (%x,%x,%x,%x,%x,%x)\n",pu8VARead[0],pu8VARead[1],pu8VARead[2],pu8VARead[3],pu8VARead[4],pu8VARead[5]));
155             ecm_polarity = 0;
156 
157             //printf("Read[5]=%x,len=%d\n",pu8VARead[5],((MS_U32)pu8Write- (MS_U32)pu8Read) );
158             if (pu8VARead[5] == 0x80)
159             {
160                 ecm_polarity = NSK2HDX_EVEN_ECM; // EVEN
161             }
162             else if (pu8VARead[5] == 0x81)
163             {
164                 ecm_polarity = NSK2HDX_ODD_ECM; // ODD
165             }
166             else
167             {
168                 printf("there is error at packet data,%x\n",DmxIdSect);
169                 goto ProcEnd;
170                 //NDS_ASSERT(FALSE, , "[%s]-[%d]\n", __FUNCTION__, __LINE__);
171             }
172 
173 
174             if( ECMFlags[DmxIdSect][ecm_polarity] == 0 )
175             {
176                 if(last_ecm_polarity[DmxIdSect] != ecm_polarity)
177                 {
178                     ECMFlags[DmxIdSect][ecm_polarity] = 1;
179                     last_ecm_polarity[DmxIdSect] = ecm_polarity;
180                     ECMBufCnt[DmxIdSect] ++;
181 
182                     pu8Ptr = MApi_NSK2_AllocateMemory(180*2, TRUE /*CACHED*/);
183                     if(pu8Ptr == NULL)
184                     {
185                         NSK_ERROR(("null pointer from allocate memory\n"));
186                         continue;
187                     }
188                     pECMBufBack[DmxIdSect][ECMBufCnt[DmxIdSect]] = pu8Ptr;
189 
190                     memcpy(pu8Ptr,&pu8VARead[8],180);
191 
192                     //printf("call NSK2HDX_EcmArrived, conn = %x, polarity = %x, DmxIdSect = %x\n",connection,ecm_polarity,DmxIdSect);
193                     //printf("call NSK2HDX_EcmArrived, conn = %x, polarity = %x, DmxIdSect = %x\n",connection,ecm_polarity,DmxIdSect);
194                     //printf("polarity=%x, ",ecm_polarity);
195                     //printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",pu8Ptr[0],pu8Ptr[1],pu8Ptr[2],pu8Ptr[3],pu8Ptr[4],pu8Ptr[5],pu8Ptr[6],pu8Ptr[7],pu8Ptr[8],pu8Ptr[9]);
196                     //printf("before calling ecm arrive = %d\n",MsOS_GetSystemTime());
197                     //connection needs to modify....
198                     NSK2HDX_EcmArrived(connection, Pids[DmxIdSect], (NDS_UBYTE *)pu8Ptr/* RPC SIZECONST(256) */, ecm_polarity /*polarity*/);
199                     //printf("end of NSK2HDX_EcmArrived\n");
200                     //printf("end of calling ecm arrive = %d\n",MsOS_GetSystemTime());
201                     //NSK2Util_PrintPacket(&pu8VARead[0],188);
202                 }
203             }
204         }
205 
206     ProcEnd:
207         MsOS_ReleaseMutex(_s32ECMFLTMutexId);
208 
209     } // Task while loop
210 }
211 
212 
213 
214 // Data callback function for event setting.
215 // Callback function inform user thread the section status.
216 // If in Polling mode, user thread need to polling filter status by themselves.
_NSK2_ECMDFLT_DataCb(MS_U8 u8DmxId,DMX_EVENT enFilterStatus)217 static void _NSK2_ECMDFLT_DataCb(MS_U8 u8DmxId, DMX_EVENT enFilterStatus)
218 {
219     MS_U8 connection;
220 
221     if(enFilterStatus == DMX_EVENT_DATA_READY)
222     {
223     	//MsOS_DelayTaskUs(1000);
224         connection = ECM_Connection[u8DmxId];
225         //printf("ecm buffer DATA_READY, u8DmxId = %x, connection = %x\n",u8DmxId,connection);
226 		MsOS_SetEvent(_s32ECMFLTEventId, ( (u8DmxId) | (connection<<8) | ECMPacketArrive) );
227 
228         //this delay is to separate the same ID cause the event error....
229     	MsOS_DelayTask(1);
230 	}
231     else if(enFilterStatus == DMX_EVENT_BUF_OVERFLOW)
232     {
233         printf("ecm buffer overflow\n");
234         MApi_DMX_Stop(u8DmxId);
235         MApi_DMX_Start(u8DmxId);
236     }
237 }
238 
239 /*****************************************************************************\
240   \ global functions
241 \*****************************************************************************/
242 
243 
NSK2HDX_SetEcmLog(MS_U32 * bEn)244 MS_U32 NSK2HDX_SetEcmLog(MS_U32 *bEn)
245 {
246     _bEcm_log = *bEn;
247     return TRUE;
248 }
249 
250 //use our tsp to do ecm filter...
251 //so, the function body is porting on middleware directly...
252 
NSK2_ECMFLT_Init(void)253 MS_U32 NSK2_ECMFLT_Init(void)
254 {
255     //NSK_TRACE(("enter NSK2_ECMFLT_Init\n"));
256     if(_u8EcmFltIsInit == FALSE)
257     {
258         //NSK_TRACE(("CreateEventGroup\n"));
259         _s32ECMFLTEventId = MsOS_CreateEventGroup("ECMFLT_Event");
260         if (_s32ECMFLTEventId < 0)
261         {
262             NSK_ERROR(("CreateEvent fail\n"));
263             return MDL_ECMFLT_FAIL;
264         }
265         //NSK_TRACE(("_s32ECMFLTEventId = %d\n",_s32ECMFLTEventId));
266 
267         _s32ECMFLTMutexId = MsOS_CreateMutex(E_MSOS_FIFO, "ECMFLT_Mutex", MSOS_PROCESS_SHARED);
268         if (_s32ECMFLTMutexId < 0)
269         {
270             NSK_ERROR(("CreateMutex fail\n"));
271             MsOS_DeleteEventGroup(_s32ECMFLTEventId);
272             return MDL_ECMFLT_FAIL;
273         }
274 
275         _pECMDFLTTaskStack = MApi_NSK2_AllocateMemory(ECMFLT_TASK_STACK_SIZE, TRUE); //_u8ECMDFLT_StackBuffer;
276         if(_pECMDFLTTaskStack == NULL)
277         {
278             NSK_ERROR(("null pointer from allocate memory\n"));
279 
280             return FALSE;
281         }
282         _s32ECMDFLTTaskId = MsOS_CreateTask((TaskEntry)_NSK2_ECMDFLT_Isr_Proc,
283                                             (MS_U32)NULL,
284                                             E_TASK_PRI_HIGH/*E_TASK_PRI_HIGH*/,
285                                             TRUE,
286                                             NULL,
287                                             ECMFLT_TASK_STACK_SIZE,
288                                             "ECMFLT_ISR_Task");
289         if (_s32ECMDFLTTaskId < 0)
290         {
291             NSK_ERROR(("CreateTask fail\n"));
292             MsOS_DeleteEventGroup(_s32ECMFLTEventId);
293             MsOS_DeleteMutex(_s32ECMFLTMutexId);
294             return MDL_ECMFLT_FAIL;
295         }
296         _u8EcmFltIsInit = TRUE;
297     }
298     else
299     {
300         //NSK_TRACE(("EMMFlt had been initialed\n"));
301     }
302 
303 
304 	MS_U16 i;
305 
306 	for(i=0;i<MaximumDmxId;i++)
307 	{
308 		ECM_Connection[i]=0xff;
309 	}
310 
311     NSK2HDX_SetEcmHwInfo(ECMRecvieBuf);
312     return MDL_ECMFLT_OK;
313 }
314 
315 
NSK2HDX_RequestEcm(NDS_ULONG x_connection,NDS_USHORT ecm_pid)316 NDS_STATUS32 NSK2HDX_RequestEcm(NDS_ULONG x_connection, NDS_USHORT ecm_pid)
317 {
318     NSK_TRACE(("enxter NSK2HDX_RequestEcm\n"));
319     NSK_TRACE(("x_connection = %x, ecm_pid = %x\n",x_connection,ecm_pid));
320 
321     MS_U8 pattern[16], mask[16], nmask[16];
322     MS_U8                                  DmxIdSect;
323     DMX_FILTER_TYPE                        FilterType;
324     MS_U8*                                 pu8BufAddr;
325     DMX_Flt_info                           FltInfo;
326     MS_U16                                 u16Pid = ecm_pid;
327 
328     memset(pattern,0x0,16);
329     memset(mask,0x0,16);
330     memset(nmask,0x0,16);
331 
332 
333     if(x_connection == 1)			//file In
334 	{
335 	    //char	FileName[50]="NSK2_D_EcmFilter.mpg";
336 	    if(XConnFileInFlag[x_connection] == FALSE)
337         {
338             XConnFileInFlag[x_connection] = TRUE;
339             _gecm_pid[x_connection] = ecm_pid;
340         }
341         else
342         {
343             if(ecm_pid == _gecm_pid[x_connection])
344                 return NSK2HDX_OK;
345         }
346 
347 	    //FilterType = DMX_FILTER_TYPE_PACKET | DMX_FILTER_SOURCE_TYPE_FILE;
348         FilterType = MApi_NSK2_EcmGetFilterType(x_connection);
349 
350         //MS_U32 pPktSize = 188;
351         //appDemo_DmxFileIn_Start(FileName,&pPktSize);
352 	}
353 	else							//Live In if x_connection==0
354 	{
355 	    if(XConnFileInFlag[x_connection] == FALSE)
356         {
357             XConnFileInFlag[x_connection] = TRUE;
358             _gecm_pid[x_connection] = ecm_pid;
359         }
360         else
361         {
362             if(ecm_pid == _gecm_pid[x_connection])
363                 return NSK2HDX_OK;
364         }
365 
366 		//FilterType = DMX_FILTER_TYPE_PACKET | DMX_FILTER_SOURCE_TYPE_LIVE;
367         FilterType = MApi_NSK2_EcmGetFilterType(x_connection);
368 	}
369 
370 
371     // Allocate a Filter and set Filter Basic Type
372     if (DMX_FILTER_STATUS_OK != MApi_DMX_Open(FilterType, &DmxIdSect))
373     {
374         NSK_ERROR(("[%s] Allocate filter fail \n",__FUNCTION__));
375     }
376 
377     NSK_TRACE(("Req DmxIdSect = %x \n",DmxIdSect));
378 
379     // Here we use pre-defined physical address of reserved section buffer.
380     // [Note] The section buffe MUST be continus in physical address space.(for DMA usage)
381 
382     pu8BufAddr = (MS_U8*)MApi_NSK2_AllocateMemory(ECMDMX_BufferSize, FALSE);
383     if(pu8BufAddr == NULL)
384     {
385         NSK_ERROR(("null pointer from allocate memory\n"));
386         return NSK2HDX_FAIL;
387     }
388     memset(pu8BufAddr, 0 , ECMDMX_BufferSize);
389 
390     // Transfer Virtual Address to Phisical Hardware Address
391     // Section buffer is structed as ring buffer, keep 4 pointer of start,end ,read and write.
392     FltInfo.Info.SectInfo.SectBufAddr = MsOS_VA2PA((MS_VIRT)pu8BufAddr);
393 
394     //NSK_TRACE(("Physical Address = %08lx\n" ,FltInfo.Info.SectInfo.SectBufAddr));
395     // Set buffer size
396     FltInfo.Info.SectInfo.SectBufSize =     ECMDMX_BufferSize;
397     //NSK_TRACE(("Size = %08lx\n" ,FltInfo.Info.SectInfo.SectBufSize));
398 
399 
400     FltInfo.Info.SectInfo.SectMode    =  DMX_SECT_MODE_CONTI;
401 
402     // <DMX_EVENT_DATA_READY/DMX_EVENT_BUF_OVERFLOW>
403     // Event trigger condition for driver, Driver will call ap's callback  < CallBack Mode Type2 >
404     FltInfo.Info.SectInfo.Event        =     DMX_EVENT_DATA_READY | DMX_EVENT_BUF_OVERFLOW | DMX_EVENT_CB_SELF ;
405 
406     // Set the pointer of the event CB function into Demux driver
407     FltInfo.Info.SectInfo.pNotify =    &_NSK2_ECMDFLT_DataCb;
408 
409     // Set Advanced Filter infomation
410     if (DMX_FILTER_STATUS_OK != MApi_DMX_Info( DmxIdSect, &FltInfo, &FilterType, TRUE))
411     {
412         NSK_ERROR(("[%s] MApi_DMX_Info fail \n",__FUNCTION__));
413     }
414 
415     // Set Filter PID --> Section PID
416     if (DMX_FILTER_STATUS_OK != MApi_DMX_Pid( DmxIdSect , &u16Pid , TRUE))
417     {
418         NSK_ERROR(("[%s] MApi_DMX_Pid fail \n",__FUNCTION__));
419     }
420 
421     //keep PIDs, buffer.
422     Pids[DmxIdSect] = u16Pid;
423     ECMAllocBuf[DmxIdSect] = pu8BufAddr;
424 
425 	//printf("Alloc ECM BUF:%x \n",ECMAllocBuf[DmxIdSect]);
426     ECM_Connection[DmxIdSect] = x_connection;
427 
428 
429     ECMBufCnt[DmxIdSect] = 0;
430     ECMFlags[DmxIdSect][0] = ECMFlags[DmxIdSect][1] = 0;
431     last_ecm_polarity[DmxIdSect] = 2;
432 
433 
434 
435     // Reset Section filter and section Buffer status;
436     MApi_DMX_SectReset(DmxIdSect);
437 
438 
439     // Set Section Match pattern
440     // The Match pattern is used for Getting specific section
441     // Pattern[16] =  Pattern for match
442     // Mask[16]    =  Match Mask : set 1 for match / 0 for ignore
443     MApi_DMX_SectPatternSet(DmxIdSect, pattern, mask, nmask, 16);
444 
445 
446     // Start Filter and record section into Section Buffer.
447     if (DMX_FILTER_STATUS_OK!= MApi_DMX_Start(DmxIdSect))
448     {
449         NSK_ERROR(("enable section filter fail\n"));
450     }
451 
452     NSK_TRACE(("leave NSK2HDX_RequestEcm\n"));
453 
454     return NSK2HDX_OK;
455 }
456 
457 
NSK2HDX_StopEcm(NDS_ULONG x_connection,NDS_USHORT ecm_pid)458 NDS_STATUS32 NSK2HDX_StopEcm(NDS_ULONG x_connection, NDS_USHORT ecm_pid)
459 {
460 
461     MsOS_ObtainMutex(_s32ECMFLTMutexId,MSOS_WAIT_FOREVER);
462 
463     //NSK_TRACE(("enxter NSK2HDX_StopEcm\n"));
464     NSK_TRACE(("x_connection = %x, ecm_pid = %x\n",x_connection,ecm_pid));
465 
466 	MS_U16 DmxIdSect = 0;
467 
468 	MS_U16 FoundInList[0xff]={0};
469 	MS_U8 Founded = 0;
470 
471     XConnFileInFlag[x_connection] = FALSE;
472 
473 #if 0
474     if(x_connection == 1)
475     {
476         appDemo_DmxFileIn_Stop();
477     }
478 #endif
479     //it needs to free DMX filter.......
480 
481 	for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
482 	{
483 		//printf("Q_DmxIdSect:%x\n",ECM_Connection[DmxIdSect]);
484 	}
485 
486 		for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
487 	{
488 		//printf("Q_Pids[DmxIdSect]:%x\n",Pids[DmxIdSect]);
489 	}
490 
491 	for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
492     {
493         if ((ECM_Connection[DmxIdSect] == x_connection) && (ecm_pid == Pids[DmxIdSect]))
494         {
495         	ECM_Connection[DmxIdSect] = 0xff;
496             FoundInList[DmxIdSect] = 1;
497 			Founded = 1;
498             NSK_TRACE(("DmxIdSect found is = %d\n",DmxIdSect));
499             break;
500         }
501     }
502 
503 
504     if(Founded == 0)
505     {
506         NSK_ERROR(("can't find pid to stop\n"));
507 		MsOS_ReleaseMutex(_s32ECMFLTMutexId);
508 		return NSK2HDX_INVALID_REQUEST;
509     }
510     else
511     {
512         NSK_TRACE(("DmxIdSect = %x\n",DmxIdSect));
513     }
514 
515 
516     for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
517     {
518         if( FoundInList[DmxIdSect] == 1)
519         {
520         	// Stop Filter
521     	 	MApi_DMX_Stop(DmxIdSect);
522         	MApi_DMX_Close(DmxIdSect);
523 
524         	Pids[DmxIdSect] = 0xffff;
525 
526         	// Free Filter.
527         	//MApi_DMX_Close(DmxIdSect);
528 
529         	Pids[DmxIdSect] = 0xffff;
530         	ECMBufCnt[DmxIdSect] = 0;
531         	ECMFlags[DmxIdSect][0] = ECMFlags[DmxIdSect][1] = ECMStopFlag;
532 
533         	//free allocate buffer...Jeff, need to implement
534         	//MsOS_FreeMemory((MS_U8*)ECMAllocBuf[DmxIdSect], gs32NonCachedPoolID);
535         }
536 
537     }
538     NSK_TRACE(("leave NSK2HDX_StopEcm\n"));
539 
540     MsOS_ReleaseMutex(_s32ECMFLTMutexId);
541 
542     return NSK2HDX_OK;
543 }
NSK2HDX_EcmProcessingFinished(NDS_USHORT ecm_pid,NDS_UBYTE * ecm_buf,NDS_UBYTE polarity)544 NDS_STATUS32 NSK2HDX_EcmProcessingFinished(NDS_USHORT ecm_pid, NDS_UBYTE *ecm_buf/* RPC SIZECONST(256) */, NDS_UBYTE polarity)
545 {
546     NSK_TRACE(("ecm_buf = 0x%p, ecm_pid = 0x%x, polarity = 0x%x\n",ecm_buf,ecm_pid,polarity));
547 
548     MS_U8 DmxIdSect = 0;
549     MS_U8 i,found_in_list;
550 
551     found_in_list=0;
552     //it needs to free DMX filter.......
553 
554     for(DmxIdSect = 0 ; DmxIdSect<MaximumDmxId; DmxIdSect++)
555     {
556         for(i=0;i<ECMRecvieBuf;i++)
557 	{
558 	    if(ecm_buf == pECMBufBack[DmxIdSect][i])
559 	    {
560 	        pECMBufBack[DmxIdSect][i] = 0;
561 		found_in_list = 1;
562 		break;
563 	    }
564 	}
565 	if(found_in_list == 1)
566 	{
567 	    break;
568 	}
569     }
570 
571 
572     //printf("Free DmxIdSect:%x\n",DmxIdSect);
573 
574     ECMBufCnt[DmxIdSect] --;
575     ECMFlags[DmxIdSect][polarity] = 0;
576 
577     if(plastECM != ecm_buf)	//patch double release bug of verifier lib, 2014Dec15
578         MApi_NSK2_FreeMemory(ecm_buf, TRUE);
579 
580     plastECM = ecm_buf;
581 
582     NSK_TRACE(("leave NSK2HDX_EcmProcessingFinished\n"));
583 
584     return NSK2HDX_OK;
585 }
586