数字电视epg信息的自动清理、增加记录和查找获取方法

文档序号:7615241阅读:301来源:国知局
专利名称:数字电视epg信息的自动清理、增加记录和查找获取方法
技术领域
本发明属于数字电视机技术领域,更明确地说涉及数字电视EPG信息的自动清理、增加记录和查找获取方法的设计。
背景技术
数字电视接收终端产品中,电子节目指南(Electronic Program Guide)EPG是与消费者关系非常密切的一项功能。通过电子节目指南,消费者可以了解各频道节目未来的播放情况、进行节目预约、阅读剧情简介、获取数字传媒的各种信息等等。
传统的EPG信息的自动删除、增加记录和查找获取方法没有自动维护功能,不能防止数据溢出,工作不够稳定。同时,其信息存储和检索速度较慢,调用接口也较麻烦,不利于移植推广。

发明内容
本发明地目的,就在于克服上述缺点和不足,提供一种完整、简单、易维护的数字电视EPG信息的自动清理、增加记录和查找获取方法。它具有自动维护功能,可以防止数据溢出,工作十分稳定。同时,其信息存储和检索速度快,调用接口简单。而且具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。
为了达到上述目的,本发明包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分。其中自动清理部分包括以下步骤
①确定内存中所有节目共用的EPG信息的记录空间和最大记录条数,以保持EPG信息中所有信息的时间差不超过内存中保留EPG信息的时间,设定清理EPG信息的时间周期为1天,防止长时间工作时溢出;
②当EPG记录总数>0时,检索出当前最新记录的时间;
③计算出门限时间,亦即最新记录的时间减EPG信息保留的时间(缺省为7天);
④删除超出门限时间的记录;
⑤更新EPG信息记录总数并重新整理信息记录。
本发明的所有频道共享一块内存,作为电子节目指南的信息存储区。但该内存的电子节目指南信息存储区可以有不同的划分,因此其最大记录数量是可调的。
增加EPG信息记录部分包括以下步骤
①调整记录起始时间时区;
②获取EPG信息记录插入点,包括以下分步骤
(1)检测EPG信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测EPG存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当EPG存储区不满时,根据service-id和event-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将EPG信息记录总数加1;
③判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的EPG信息记录;
④当记录插入点索引≥0时,将当前记录拷贝到EPG信息数组中。
增加当前/下一个信息记录部分包括以下步骤
①获取当前/下一个信息记录插入点,包括以下分步骤
(1)检测当前/下一个信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测当前/下一个存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当当前/下一个存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将当前/下一个信息记录总数加1;
②判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的当前/下一个信息记录;
③当记录插入点索引≥0时,将当前记录拷贝到当前/下一个信息数组中。
查找获取部分包括以下步骤
①判断输入参数是否有效,当输入参数无效时,直接返回;
②当输入参数有效时,查找第一项匹配的EPG信息记录和总共匹配的记录数量;
③比较待查询记录索引和匹配的记录数量,当待查询记录索引≥匹配的记录数量时无获取,当待查询记录索引<匹配的记录数量时,获取一条EPG信息。
本发明查找获取一条EPG信息或者存储一条EPG信息直接采用折半查找法。定位及查找速度快。它只有4个关键性接口函数,其中两个用于数据注入、两个用于数据获取。
本发明的任务就是这样完成的。
本发明提供了一种完整、简单、易维护的数字电视EPG信息的自动清理、增加记录和查找获取方法。它具有自动维护功能,可设定信息保留时间,可每天进行一次垃圾清理,以防止数据溢出,能确保长时间工作稳定。同时,其信息存储和检索速度快,调用接口简单。它还具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。


图1为本发明自动清理的流程图。
图2为图1中清理过期EPG信息的流程图。
图3为增加EPG信息记录的流程图。
图4为图3中获取EPG信息记录插入点的流程图。
图5为增加Now/Next信息记录的流程图。
图6为图5中获取Now/Next信息记录插入点的流程图。
图7为获取一条EPG信息的流程图。
具体实施例方式
实施例1。一种数字电视EPG信息的自动清理、增加记录和查找获取方法,包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分。如图1所示,其中自动清理部分包括以下步骤
①确定内存中所有节目共用的EPG信息的记录空间和最大记录条数,以保持EPG信息中所有信息的时间差不超过内存中保留EPG信息的时间,设定保留EPG信息的时间为延迟1天,防止长时间工作时溢出;
②当EPG记录总数>0时,检索出当前最新记录的时间;
③计算出门限时间,亦即最新记录的时间减保留EPG信息的时间;
④删除超出门限时间的记录;
⑤更新EPG信息记录总数并重新整理信息记录。
其源代码为
  //保持EPG信息中的所有信息时间差不超过DaysToKeep,以防止长时间工作时溢出BOOL EPG::EPGList_GabageRemove(void){int i=0,J=0;int temp_Year;UCHAR8 temp_Month,temp_Day;long LatestTime,FirstTime,TempTime;int GabageCount=0;if(Weekly_EPG_Info_Number<=0)  return TRUE;  temp_Year=Weekly_EPG_Info
.start_time.Year;  temp_Month=Weekly_EPG_Info
.start_time.Month;  temp_Day=Weekly_EPG_Info
.start_time.Day;  LatestTime=(temp_Year<<16)|(temp_Month<<8)|temp_Day;  FirstTime=LatestTime;  //找出最近的时间  for(i=0;i<Weekly_EPG_Info_Number;i++)   {    temp_Year=Weekly_EPG_Info[i].start_time.Year;  temp_Month=Weekly_EPG_Info[i].start_time.Month;  temp_Day=Weekly_EPG_Info[i].start_time.Day;  TempTime=(temp_Year<<16)(temp_Month<<8)|temp_Day;  if(LatestTime<TempTime)   {  LatestTime=TempTime;<!-- SIPO <DP n="4"> --><dp n="d4"/>   }  }  temp_Day=LatestTime&amp;0x000000ff;  temp_Month=(LatestTime&amp;0x0000ff00)>>8;  temp_Year=(LatestTime&amp;0xffff0000)>>16;  //计算门限时间,以DaysToKeep为限  if(temp_Day>DaysToKeep)  temp_Day=temp_Day-DaysToKeep;  else if((temp_Month==2)‖(temp_Month==4)‖(temp_Month==6)  ‖(temp_Month==8)‖(temp_Month==9)‖(temp_Month==11)  ‖(temp_Month==1))   {  if(temp_Month-1==0)   {   temp_Month=12;   temp_Year--;   }   else   temp_Month--;   temp_Day=31+temp_Day-DaysToKeep;   }  else if((temp_Month==5)‖(temp_Month==7)‖(temp_Month==10)‖(temp_Month==12))   {  temp_Month--;  temp_Day=30+temp_Day-DaysToKeep;   }  else if(temp_Month==3)    {  if((temp_Year%400)==0)‖(((temp_Year%4)==0)&amp;&amp;((temp_Year%100)!=0)))   {<!-- SIPO <DP n="5"> --><dp n="d5"/>  temp_Month--;  temp_Day=29+temp_Day-DaysToKeep;  }  else  {  temp_Month--;  temp_Day=28+temp_Day-DaysToKeep;   }   }  printf(″Gate Time is%d,%d,%d\n″,temp_Year,temp_Month,temp_Day);  //删除超出时间限制的信息  FirstTime=(temp_Year<<16)|(temp_Month<<8)|temp_Day;  for(i=0;i<Weekly_EPG_Info_Number;i++)   {   temp_Year=Weekly_EPG_Info[i].start_time.Year;   temp_Month=Weekly_EPG_Info[i].start_time.Month;   temp_Day=Weekly_EPG_Info[i].start_time.Day;   TempTime=(temp_Year<<16)|(temp_Month<<8)|temp_Day;   if(FirstTime>Temp Time)   {  memset((void*)&amp;Weekly_EPG_Info[i],0,sizeof(Weekly_EPG_INFO_STRUCT));  GabageCount++;   }  }  if(GabageCount==0)  return TRUE;  //重新整理EPG信息记录  int HoleIndex=0,DefragmentIndex;  int k=Weekly_EPG_Info_Number;  while(k)<!-- SIPO <DP n="6"> --><dp n="d6"/>  {   for(i=HoleIndex;i<Weekly_EPG_Info_Number;i++)  {  if(Weekly_EPG_Info[i].service_id==0)  {  HoleIndex=i;  break;  }   }  for(j=HoleIndex;j<Weekly_EPG_Info_Number;j++)   {   if(Weekly_EPG_Info[j].service_id|=0)   {   DefragmentIndex=j;   break;   }   }  memcpy((void*)&amp;Weekly_EPG_Info[HoleIndex],  (void*)&amp;Weekly_EPG_Info[DefragmentIndex],  sizeof(Weekly_EPG_INFO_STRUCT));  memset((void*)&amp;Weekly_EPG_Info[DefragmentIndex],0,sizeof(Weekly_EPG_INFO_STRUCT));  HoleIndex++;  k--;  if(HoleIndex>=DefragmentIndex)   break;  }  Weekly_EPG_Info_Number=Weekly_EPG_Info_number-GabageCount;  return TRUE;}
如图3~图4所示,增加EPG信息记录部分包括以下步骤
①调整记录起始时间时区;
②获取EPG信息记录插入点,包括以下分步骤
(1)检测EPG信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测EPG存储区是否已满,当EPG存储区已满时,
即进入下一步骤;
③当EPG存储区不满时,根据service-id和evemt-id进行检索
(1)如果检索到已有该记录,即进入下一步骤;
(2)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将EPG信息记录总数加1;
④判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的EPG信息记录;
⑤当记录插入点索引≥0时,将当前记录拷贝到EPG信息数组中。
其源代码为
∥增加一个新的EPG信息BOOL EPG::AddEPGList(tagDVBEIT_EVENT_ENTRY_STRUCT*pEPG){  int IndexofNewInfo;//---------------------------时区调整---------------------------------------------------  if((*pEPG).start_time.Hour<16)  {  (*pEPG).start_time.Hour=(*pEPG).start_time.Hour+China_TimeZone;  }  else  {  (*pEPG).start_time.Hour=(*pEPG).start_time.Hour+China_TimeZone-24;  (*pEPG).start_time.Day=(*pEPG).start_time.Day+1;  if((*pEPG).start_time.Month==1‖(*pEPG).start_time.Month==3‖(*pEPG).start_time.Month==5  ‖(*pEPG).start_time.Month==7‖(*pEPG).start_time.Month==8‖(*pEPG).start_time.Month==10  ‖(*pEPG).start_time.Month==12)  {<!-- SIPO <DP n="8"> --><dp n="d8"/>  if((*pEPG).start_time.Day>31)  {  (*pEPG).start_time.Day=1;  (*pEPG).start_time.Month=(*pEPG).start_time.Month+1;  if((*pEPG).start_time.Month==13)  {  (*pEPG).start_time.Month=1;  (*pEPG).start_time.Year=(*pEPG).start_time.Year+1;  }  }  }  else if((*pEPG).start_time.Month==4‖(*pEPG).start_time.Month==6  ‖(*pEPG).start_time.Month==9‖(*pEPG).start_time.Month==11)  {  if((*pEPG).start_time.Day>30)  {  (*pEPG).start_time.Day=1;  (*pEPG).start_time.Month=(*pEPG).start_time.Month+1;  if((*pEPG).start_time.Month==13)  {  (*pEPG).start_time.Month=1;  (*pEPG).start_time.Year=(*pEPG).start_time.Year+1;   }   }   }  else  {  int OddMonth=0;  if(((*pEPG)start_time.Year%400)==0‖  (((*pEPG).start_time.Year%4)==0&amp;&amp;((*pEPG).start_time.Year%100)!=0))<!-- SIPO <DP n="9"> --><dp n="d9"/>  OddMonth=1;  if((*pEPG).start_time.Day>28+OddMonth)  {  (*pEPG).start_time.Day=1;  (*pEPG).start_time.Month=(*pEPG).start_time.Month+1;  if((*pEPG).start_time.Month==13)  {  (*pEPG).start_time.Month=1;  (*pEPG).start_time.Year=(*pEPG).start_time.Year+1;  }  }  }  }//------------------------------------获取插入点-----------------------------------------  IndexofNewInfo=Get_EPG_ServiceID_Index((*pEPG).service_id,(*pEPG).event_id);  if(IndexofNewInfo==-1)  {//没有可用插入点  return FALSE;  }  else  {//将新的EPG信息记录拷贝到EPG信息库中  Weekly_EPG_Info[IndexofNewInfo].service_id=(*pEPG).service_id;  Weekly_EPG_Info[IndexofNewInfo].duration=(*pEPG).duration;  Weekly_EPG_Info[IndexofNewInfo].event_id=(*pEPG).event_id;  Weekly_EPG_Info[IndexofNewInfo].start_time.Year=(*pEPG).start_time.Year;  Weekly_EPG_Info[IndexofNewInfo].start_time.Month=(*pEPG).start_time.Month;  Weekly EPG_Info[IndexofNewInfo].start_time.Day=(*pEPG).start_time.Day;  Weekly_EPG_Infp[IndexofNewInfo].start_time.Hour=(*pEPG).start_time.Hour;  Weekly_EPG_Info[IndexofNewInfo].start_time.Minute=(*pEPG)start_time.Minute;  Weekly_EPG_Info[IndexofNewInfo].start_time.Second=(*pEPG).start_time.Second;<!-- SIPO <DP n="10"> --><dp n="d10"/>  Weekly_EPG_Info[IndexofNewInfo].end_time.Year=(*pEPG).end_time.Year;  Weekly_EPG_Info[IndexofNewInfo].end_time.Month=(*pEPG).end_time.Month;  Weekly_EPG_Info[IndexofNewInfo].end_time.Day=(*pEPG).end_time.Day;  Weekly_EPG_Info[IndexofNewInfo].end_time.Hour=(*pEPG).end_time.Hour;  Weekly_EPG_Info[IndexofNewInfo].end time.Minute=(*pEPG).end_time.Minute;  Weekly_EPG_Info[IndexofNewInfo].end_time.Second=(*pEPG).end_time.Second;  Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_length=(*pEPG).short_event_desc.event_name_length;  Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_length=(*pEPG).short_event_desc.text_length;  if(Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_length>=30)  {  Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_length=30;  memcpy((char*)Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pEPG).short_event_desc.event_name_str,30);  Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_str[29]=′\0′;  }  else  strcpy((char*)Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pEPG).short_event_desc.event_name_str);  if(Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_length>=30)  {  Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_length=30;  memcpy((char*)Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_str,(char*)(*pEPG).short_event_desc.text_str,30);  Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_str[29]=′\0′;  }  else  strcpy((char*)Weekly_EPG_Info[IndexofNewInffo].short_event_desc.text_str,(char*)(*pEPG).short_event_desc.text_str);<!-- SIPO <DP n="11"> --><dp n="d11"/>  }  return TRUE;}//查找指定serviceID和eventID的数组下标,如果没有找到,就分配一个//serviceID和eventID按照升序排列int EPG::Get_EPG_ServiceID_Index(UINT16serviceID,UINT16eventID){  int i;  BOOL foundIt;  int IndexFound;  if(Weekly_EPG_Info_Number==0)  {  Weekly_EPG_Info_Number++;  return 0;  }  if(Weekly_EPG_Info_Number>=Max_Weekly_EPG_Info_Number)  {  printf(″Now EPG storage full!\n″);  return-1;  }  //检查是否存在该serviceID和eventID,如果存在,直接返回索引  foundIt=QuickFind(serviceID,eventID,TRUE,&amp;IndexFound);//printf(″Index is%d,Found result is%d\n″,IndexFound,foundIt);  if(foundIt)  return IndexFound;  else  //如果不存在eventID,分配一个新的  {  for(i=Weekly_EPG_Info_Number-1;i>=IndexFound;i--)  memcpy((void*)&amp;Weekly_EPG_Info[i+1],(void*)&amp;Weekly_EPG_Info[i],<!-- SIPO <DP n="12"> --><dp n="d12"/>sizeof(Weekly_EPG_INFO_STRUCT));  i++;  memset((void*)&amp;Weekly_EPG_Info[i],0,sizeof(Weekly_EPG_INFO_STRUCT));  Weekly_EPG_Info_Number++;  return IndexFound;  }return IndexFound;}
如图5~图6所示,增加当前/下一个信息记录部分包括以下步骤
①获取当前/下一个信息记录插入点,包括以下分步骤
(1)检测当前/下一个信息记录总数,当它=0时,返回0;
(2)当它不等于0时,检测当前/下一个存储区是否已满,当EPG存储区已满时,返回-1;
(3)当当前/下一个存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即返回该记录的索引;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将当前/下一个信息记录总数加1,返回该记录的索引;
②判断记录插入点索引的数值
(1)当记录插入点索引<0时,不增加新的当前/下一个信息记录;
(2)当记录插入点索引≥0时,将当前记录拷贝到当前/下一个信息数组中。
增加EPG信息记录、增加EPG当前/下一个信息记录部分的源代码如下
//增加一个新的当前/下一个event信息BOOL EPG::AddNowNextInfo(tagDVBEIT_EVENT_ENTRY_STRUCT*pShortEvent){int IndexofNewInfo;//----------------获取插入点--------------------------------------------------------------------------  IndexofNewInfo=Get_NowNext_ServieeID_Index((*pShortEvent).service_id,(*pShortEvent).NextFlag);  if(IndexofNewInfo==-1)<!-- SIPO <DP n="13"> --><dp n="d13"/>  {  printf(″EPG Storage Full,Error\n″);  return FALSE;  }  else   { Now_Next_Info[IndexofNewInfo].NextFlag=(*pShortEvent).NextFlag;  Now_Next_Info[IndexofNewInfo].service_id=(*pShortEvent).service_id;  Now_Next_Info[IndexofNewInfo].duration=(*pShortEvent).duration;  Now_Next_Info[IndexofNewInfo].event_id=(*pShortEvent).event_id;  Now_Next_Info[IndexofNewInfo].start_time.Year=(*pShortEvent).start_time.Year;  Now_Next_Info[IndexofNewInfo].start_time.Month=(*pShortEvent).start_time.Month;  Now_Next_Info[IndexofNewInfo].start_timeDay=(*pShortEvent).start_time.Day;  Now_Next_Info[IndexofNewInfo].start_time.Hour=(*pShortEvent).start_time.Hour;    Now_Next_Info[IndexofNewInfo].start_time.Minute=(*pShortEvent).start_time.Minute;  Now_Next_Info[IndexofNewInfo].start_time.Second=(*pShortEvent).start_time.Second;  Now_Next_Info[IndexofNewInfo].end_time.Year=(*pShortEvent).end_time.Year;  Now_Next_Info[IndexofNewInfo].end_time.Month=(*pShortEvent).end_time.Month;  Now_Next_Info[IndexofNewInfo].end_time.Day=(*pShortEvent).end_time.Day;  Now_Next_Info[IndexofNewInfo].end_time.Hour=(*pShortEvent).end_time.Hour;  Now Next_Info[IndexofNewInfo].end_time.Minute=(*pShortEvent).end_time.Minute;  Now_Next_Info[IndexofNewInfo].end_time.Second=(*pShortEvent).end_time.Second;  Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_length=(*pShortEvent).short_event_desc.event_name_length;  Now_Next_Info[IndexofNewInfo].short_event_desc.text_length=(*pShortEvent).short_event_desc.text_length;  if(Now_Next_Info[IndexofNewInfo].short_evgnt_desc.event_name_length>=30)  {  Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_length=30;  memcpy((char*)Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pShortEvent).short_event_desc.event_name_str,30);<!-- SIPO <DP n="14"> --><dp n="d14"/>  Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_str[29]=′\0′;  }  else  strcpy((char*)Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pShortEvent).short_event_desc.event_name_str);  }  return TRUE;}//查找指定serviceID的数组下标,如果没有找到,就分配一个//serviceID按照升序排列int EPG::Get_NowNext_ServiceID_Index(UINT16serviceID,BOOL NextFlag){  int i;  BOOL foundIt;  int IndexFound;  if(Now_Next_Info_Numbef==0)  {  Now_Next_Info_Number++;  return 0;  }if(Now_Next_Info_Number>=Max_Now_Next_Info_Number)  {  printf(″Now EPG storage full!\n″);  returt-1;  }  //检查是否存在该serviceID和eventID,如果存在,直接返回索引  foundIt=QuickFind(serviceID,(int)NextFlag,FALSE,&amp;IndexFound);  if(foundIt)  return IndexFound;  else<!-- SIPO <DP n="15"> --><dp n="d15"/>  //如果不存在eventID,分配一个新的  {  for(i=Now_Next_Info_Number-1;i>=IndexFound;i--)  memcpy((void*)&amp;Now_Next_Info[i+1],(void*)&amp;Now_Next_Info[i],sizeof(Now_Next_INFO_STRUCT));  i++;  memset((void*)&amp;Now_Next_Info[i],0,sizeof(Now_Next_INFO_STRUCT));  Now_Next_Info_Number++;  return IndexFound;  }  return IndexFound;}
如图7所示,EPG信息记录查找获取部分包括以下步骤
①判断输入参数是否有效,当输入参数无效时,无获取;
②当输入参数有效时,查找第一项匹配的EPG信息记录和总共匹配的记录数量;
③比较待查询记录索引和匹配的记录数量,当待查询记录索引≥匹配的记录数量时无获取,当待查询记录索引<匹配的记录数量时,获取一条EPG信息。
其源代码如下
  //输入serviceID和日期以及当天第几条EPG,返回指向该EPG记录的指针,没有则为空//注意IndexOfRecords取值从0开始  Weekly_EPG_INFO_STRUCT*EPG::Get_EPG_Info_InOneDay(UINT16 serviceID,UCHAR8 Date,int  IndexOfRecords)  {  int RecordsFound=0;  int firstIndex;  if(Date>31‖Date<=0‖IndexOfRecords<0)  return NULL;  firstIndex=QuickLocateMultiEPG(serviceID,Date,&amp;RecordsFound);<!-- SIPO <DP n="16"> --><dp n="d16"/>  if(IndexOfRecords>=RecordsFound)  {  printf(″No More EPG Records for This Day!\n″);  return NULL;  }  else  {  return&amp;(Weekly_EPG_Info[firstIndex+IndexOfRecords]);  }}//注意,此处假设EPG信息制作时,指定的节目EVENT_ID连续,即使不连续,<br/>//中间也不会插入其他节目的eventID。如果此假设不成立,则应修改本函数<br/>int EPG::QuickLocateMultiEPG(UINT16ServiceID,UCHAR8Date,int*MatchedNumber)<br/>{  int left=0;  int right=0;  int mid;  long tempID;  tempID=(ServiceID<<16)|Date;  int firstIndex=0,lastIndex=0;  right=Weekly_EPG_Info_Number-1;  if(right<0)  {  *MatchedNumber=0;  return 0;  }  mid=(right+left)/2;//定位第一个匹配纪录  while(left<=right)  {<!-- SIPO <DP n="17"> --><dp n="d17"/>  mid=(right+left)/2;  if(tempID<=((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_time.Day))  right=mid-1;  else  left=mid+1;  }  if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_time.Day))  {  firstIndex=mid;  }  else if(tempID==((Weekly_EPG_Info[mid+1].service_id<<16)|Weekly_EPG_Info[mid+1].start_time.Day))  {  firstIndex=mid+1;  }  else  {  *MatchedNumber=0;  return 0;  }//定位最后一个匹配纪录  left=0;  right=Weekly_EPG_Info_Number-1;  mid=(right+left)/2;  while(left<=right)  {  mid=(right+left)/2;  if(tempID<((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_ime.Day))  right=mid-1;  else  left=mid+1;<!-- SIPO <DP n="18"> --><dp n="d18"/>  }  if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_time.Day))  {  lastIndex=mid;  }  else if(tempID==((Weekly_EPG_Info[mid-1].service_id<<16)|Weekly_EPG_Info[mid-1].start_time.Day))  {  lastIndex=mid-1;  }  *MatchedNumber=lastIndex-firstIndex+1;  return firstIndex;  }
查找获取一条当前/下一个信息直接采用折半查找法。查找获取及折半查找的源代码如下
//获取一条当前或者下一个event信息的指针//输入service ID,Current状态。//NextFlag=FALSE,表示获取该serviceID的当前节目信息//NextFlag=TRUE,表示获取该serviceID的下一个节目信息Now_Next_INFO_STRUCT*EPG::GetNowNextInfo(UINT16 serviceID,BOOL NextFlag){  int left=0,right=0,mid=0;  long tempID=(serviceID<<16)|(int)NextFlag;  right=Now_Next_Info_Number-1;  if(right<0)  {  return NULL;  }  mid=(right+left)/2;  while(left<=right)  {<!-- SIPO <DP n="19"> --><dp n="d19"/>  mid=(right+left)/2;  if(tempID<(Now_Next_Info[mid].service_id<<16|(int)(Now_Next_Info[mid].NextFlag)))  {  right=mid-1;  }  else if(tempID>(Now_Next_Info[mid]service_id<<16|(int)(Now_Next_Info[mid].NextFlag)))  {  left=mid+1;  }  else if(tempID==(Now_Next_Info[mid].service_id<<16|(int)(Now_Next_Info[mid].NextFlag)))  {  return&amp;Now_Next_Info[mid];  }  }  if(tempID==(Now_Next_Info[mid].service_id<<16|(int)(Now_Next_Info[mid].NextFlag)))  {  return&amp;Now_Next_Info[mid];  }  return NULL;}//折半查找//FindInEPG时,serviceID和eventID联合作为关键字//FindInEPG为假时,认为是在nownext信息中搜索,此时eventID被NextFlag替代BOOL EPG::QuickFind(UINT16 ServiceID,UINT16 eventID,BOOL FindInEPG,int*IndexFound){  int left=0;  int right=0;  int mid;  UINT32tempID;<!-- SIPO <DP n="20"> --><dp n="d20"/>  tempID=(ServiceID<<16)|eventID;  if(FindInEPG)  {  right=Weekly_EPG_Info_Number-1;  if(right<0)  {  *IndexFound=0;  return FALSE;  }  mid=(right+left)/2;  while(left<=right)  {  mid=(right+left)/2;  if(tempID<((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id))  right=mid-1;  else if(tempID>((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id))  left=mid+1;  else if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id))  {  *IndexFound=mid;  return TRUE;  }  }  if(tempID<((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id))  {  *IndexFound=mid;  return FALSE;  }<!-- SIPO <DP n="21"> --><dp n="d21"/>  else if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id))   {  *IndexFound=mid;  return TRUE;   }  else   {  *IndexFound=mid+1;  return FALSE;   }  }  else//find in NowNextInfo   {  //注意此时eventID已经被NextFlag替代  right=Now_Next_Info_Number-1;  left=0;  if(right<0)   {   *IndexFound=0;   return FALSE;   }  mid=(right+ieft)/2;|(int)Now_Next_Info[1].NextFlag));  while(left<=right)   {  mid=(right+left)/2;  if(tempID<((Now_Next_Next_Info[mid].service_id<<16)|(int)Now_Next_Info[mid]NextFlag))   right=mid-1;  else if(tempID>((Now_Next_Info[mid].service_id<<16)|(int)Now_Next_Info[mid]NextFlag))<!-- SIPO <DP n="22"> --><dp n="d22"/>  left=mid+1;  else if(tempID==((Now_Next_Info[mid].service_id <<16)|(int)Now_Next_Info[mid].NextFlag))  {  *IndexFound=mid;  return TRUE;  }  }   if(tempID<((Now_Next_Info[mid].serviee_id<<16)|(int)Now_Next_Info[mid].NextFlag))  {   *IndexFound=mid;   return FALSE;  }   else if(tempID==((Now_Next_Infi[mid].service_id<<16)|(int)Now_Next_Info[mid].NextFlag))   {   *IndexFound=mid;   return TRUE;   }   else   {   *IndexFound=mid+1;   return FALSE;   }   }}void CleanEPG(void*pvParam){  while(1)<!-- SIPO <DP n="23"> --><dp n="d23"/>  {  //每天清理一次EPG数据  Delay(1000*3600*24);  EPG_DVBC.EPGList_GabageRemove();  }  return;}EPG.H#ifndef EPG_h#define EPG_h#define max_events_per_program 7*24#define NEXT TRUE#define NOW FALSEtypedef struct SHORT_EVENT_DESC_STRUCT{  /*for short_event_descriptor()*/  UCHAR8 event_name_length;  UCHAR8 event_name_str[30];//15个汉字  UCHAR8 text_length;  UCHAR8 text_str[30];//15个汉字};typedef struct EXT_EVENT_DESC_STRUCT{  /*for extended_event_descriptor()*/  UCHAR8 ISO_639_language_code[4];  int item_description_length[MAX_NUM_OF_ITEMS];  UCHAR8 item_description_char[MAX_NUM_OF_ITEMS][30];  int item_length[MAX_NUM_OF_ITEMS];  UCHAR8 item_char[MAX_NUM_OF_ITEMS][30];<!-- SIPO <DP n="24"> --><dp n="d24"/>  UCHAR8 text_length;  UCHAR8 text_char[128];  };  struct Now_Next_INFO_STRUCT  {   UINT16 service_id;   UINT16 event_id;   DVBTIME start_time;   DVBTIME end_time;   UINT32 duration;   BOOLNextFlag;   SHORT_EVENT_DESC_STRUCT short_event_desc;  };struct Weekly_EPG_INFO_STRUCT   {   UINT16 service_id;   UINT16 event_id;   DVBTIME start_time;   DVBTIME end_time;   UINT32 duration;   SHORT_EVENT_DESC_STRUCT short_event_dese;   };struct Ext_EPG_INFO_STRUCT   {   UINT16 service_id;   UINT16 event_id;   DVBTIME start_time;   DVBTIME end_time;   UINT32 duration;<!-- SIPO <DP n="25"> --><dp n="d25"/>EXT_EVENT_DESC_STRUCT ext_event_desc;};void CleanEPG(void*pvParam);class EPG{publicCORE_TASK_ID TaskID_CleanEPG;EPG();  ~EPG();  BOOL Init(void);  BOOL AddNowNewtInfo(tagDVBEIT_EVENT_ENTRY_STRUCT*pShortEvent);  BOOL AddEPGList(tagDVBEIT_EVENT_ENTRY_STRUCT*pEPG);  BOOL ADDExtEPGList(tagDVBEIT_EVENT_ENTRY_STRUCT*pExtEPG);  BOOL EPGList_GabageRemove(void);  Now_Next_INFO_STRUCT*GetNowNextInfo(UINT16 serviceID,BOOL Current);  Weekly_EPG_INFO_STRUCT*Get_EPG_Info_InOneDay(UINT16 serviceID,UCHAR8 Date,intIndexOfRecords);  int Get_Now_Next_Inft_Number(void);  int Get_Weekly_EPG_Info_Number(void);  void outputNowNextInfo(void);  void outputEPGListInfo(void);  void PrintEPGofOneDay(UINT16 ServiceID,UCHAR8 Day);  private  int Max_Now_Next_Info_Number;  int Now_Next_Info_Number;  CORE_SEM_ID EPG_LOCK1;  CORE_SEM_ID NowNext_LOCK;  int Max_Weekly_EPG_Info_Number;  int Weekly_EPG_Info_Number;  int China_TimeZone;  int Max_Ext_EPG_Info_Number;<!-- SIPO <DP n="26"> --><dp n="d26"/>  int Ext_EPG_Info_Number;  int DaysToKeep;//保留EPG的天数  Now_Next_INFO_STRUCT*Now_Next_Info;  Weekly_EPG_INFO_STRUCT*Weekly_EPG_Info;  Ext_EPG_INFO_STRUCT*Ext_EPG_Info;  BOOL QuickFind(UINT16 ServiceID,UINT16 eventID,BOOL FindInEPG,int*IndexFound);  int QuickLoeateMultiEPG(UINT16 ServiceID,UCHAR8 Date,int*MatchedNumber);  int Get_NowNext_ServiceID_Index(UINT16 serviceID,BOOL NextFlag);  int Get_EPG_ServiceID_Index(UINT16 servieeID,UINT16 eventID);  };#endif
实施例1具有自动维护功能,可设定信息保留时间,可每天进行一次垃圾清理,以防止数据溢出,能确保长时间工作稳定。同时,其信息存储和检索速度快,调用接口简单。它还具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。
权利要求
1.一种数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于它包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分,其中自动清理包括以下步骤
①确定内存中所有节目共用的EPG信息的记录空间和最大记录条数,以保持EPG信息中所有信息的时间差不超过内存中保留EPG信息的时间,设定保留EPG信息的时间,防止长时间工作时溢出;
②当EPG记录总数>0时,检索出当前最新记录的时间;
③计算出门限时间,亦即最新记录的时间减EPG信息保留的时间;
④删除超出门限时间的记录;
⑤更新EPG信息记录总数并重新整理信息记录。
2.按照权利要求1所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于增加EPG信息记录部分包括以下步骤
①调整记录起始时间时区;
②获取EPG信息记录插入点,包括以下分步骤
(1)检测EPG信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测EPG存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当EPG存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将EPG信息记录总数加1;
③判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的EPG信息记录;
④当记录插入点索引≥0时,将当前记录拷贝到EPG信息数组中。
3.按照权利要求2所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于增加当前/下一个信息记录部分包括以下步骤
①获取当前/下一个信息记录插入点,包括以下分步骤
(1)检测当前/下一个信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测当前/下一个存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当当前/下一个存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将当前/下一个信息记录总数加1;
②判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的当前/下一个信息记录;
③当记录插入点索引≥0时,将当前记录拷贝到当前/下一个信息数组中。
4.按照权利要求3所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于查找获取部分包括以下步骤
①判断输入参数是否有效,当输入参数无效时,无获取;
②当输入参数有效时,查找第一项匹配的EPG信息记录和总共匹配的记录数量;
③比较待查询记录索引和匹配的记录数量,当待查询记录索引≥匹配的记录数量时无获取,当待查询记录索引<匹配的记录数量时,获取一条EPG信息。
5.按照权利要求3所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于查找获取一条EPG信息直接采用折半查找法。
全文摘要
一种数字电视EPG信息的自动清理、增加记录和查找获取方法。它包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分。自动清理包括确定内存中共用的EPG信息的记录空间和最大记录条数,设定保留EPG信息的时间,防止长时间工作时溢出;当EPG记录总数>0时,检索出当前最新记录的时间;计算出门限时间,亦即最新记录的时间减保留EPG信息的时间;删除超出门限时间的记录;更新EPG信息记录总数并重新整理信息记录等步骤。它自动清理维护,可防止数据溢出,工作十分稳定。其信息存储和检索速度快,调用接口简单。而且具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。
文档编号H04N7/08GK1758746SQ20051004478
公开日2006年4月12日 申请日期2005年9月19日 优先权日2005年9月19日
发明者邓泽学 申请人:海信集团有限公司, 青岛海信电器股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1