📄 xp_osd_drv.c
字号:
| Same PID cannot be allocated to more than one channel +----------------------------------------------------------------------------*/ for (i = 0; i < pDemuxDev->uFilterNum; i++) { if ((pDemuxDev->filter[i].para.pid == pDmxfilter->para.pid) && (pDemuxDev->filter[i].chid != (short)ILLEGAL_CHANNEL)) { break; } } /*----------------------------------------------------------------------------+ | Attach filter to existing Channel with same PID +----------------------------------------------------------------------------*/ if (i < pDemuxDev->uFilterNum) { PDEBUG("DemuxFilterSectionSet(): New filter attached to an existing channel\n"); pDmxfilter->chid = pDemuxDev->filter[i].chid; pDmxfilter->buffer.plBQueue = pDemuxDev->filter[i].buffer.plBQueue; pDmxfilter->buffer.plEQueue = pDemuxDev->filter[i].buffer.plEQueue; } /*----------------------------------------------------------------------------+ | Create New Channel for Filter +----------------------------------------------------------------------------*/ else if (pDmxfilter->chid == ILLEGAL_CHANNEL) { DemuxAcq.channel_type = XP_CHANNEL_TYPE_PES; DemuxAcq.pid = pDmxfilter->para.pid; DemuxAcq.unload_type = XP_CHANNEL_UNLOAD_FILTER_PSI_CRC; DemuxAcq.bthreshold = 0; DemuxAcq.queue_size = pDmxfilter->buffer.ulSize; DemuxAcq.notify_data_fn = DemuxSectionCallback; if (DemuxChannelAcquire(pGlobal,pDmxfilter,&DemuxAcq)) { printk("DemuxFilterSectionSet(): Error acquiring channel for Section Filter\n"); return(-EMFILE); } pDemuxDev->chid[pDmxfilter->chid].state = XP_CHANNEL_DISABLED; } /*----------------------------------------------------------------------------+ | Disable Channel +----------------------------------------------------------------------------*/ else { os_get_mutex(hMutex); rc = xp_osi_channel_control(pGlobal,(short)pDmxfilter->chid, XP_CHANNEL_CONTROL_DISABLE); os_release_mutex(hMutex); if (rc) { printk("DemuxFilterSectionSet(): Error enabling channel for Section Filter\n"); return(-1); } pDemuxDev->chid[pDmxfilter->chid].state = XP_CHANNEL_DISABLED; } /*----------------------------------------------------------------------------+ | Create New Filter for existing channel +----------------------------------------------------------------------------*/ if (DemuxFilterAcquire(pGlobal,pDmxfilter)) { pDmxfilter->para.pid = -1; printk("DemuxFilterSectionSet(): Error acquiring Section Filter\n"); return(-EMFILE); } pDmxfilter->pid = pDmxfilter->para.pid; pDmxfilter->type = FILTER_TYPE_SEC; pDmxfilter->states = FILTER_STAT_SET; os_get_mutex(hMutex); pDemuxDev->chid[pDmxfilter->chid].inuse++; os_release_mutex(hMutex); return(0);}/*----------------------------------------------------------------------------+| DemuxFilterBucketSet+----------------------------------------------------------------------------*/static int DemuxFilterBucketSet( GLOBAL_RESOURCES *pGlobal, DEMUX_FILTER *pDmxfilter){ DEMUX_CHANNEL_ACQUIRE_TYPE DemuxAcq; PDEBUG("DemuxFilterBucketSet(): Entering\n"); if (pDmxfilter->buffer.ulSize < pDmxfilter->bucket_para.unloader.threshold*256) { printk("DemuxFilterBucketSet(): Error - Illegal Buffer size\n"); return(-1); } if (pDmxfilter->states >= FILTER_STAT_SET) { if(pDmxfilter->flags & FILTER_FLAG_MMAPPED) { printk("DemuxFilterBucketSet(): Error - filter is mmapped\n"); return(-1); } DemuxFilterReset(pGlobal,pDmxfilter); } pDmxfilter->type = FILTER_TYPE_BUCKET; pDmxfilter->states = FILTER_STAT_SET; /*----------------------------------------------------------------------------+ | Allocate Channel for Bucket Queue +----------------------------------------------------------------------------*/ DemuxAcq.channel_type = XP_CHANNEL_TYPE_BUCKET; DemuxAcq.pid = XP_CHANNEL_NULL_PID; DemuxAcq.unload_type = pDmxfilter->bucket_para.unloader.unloader_type; DemuxAcq.bthreshold = pDmxfilter->bucket_para.unloader.threshold; DemuxAcq.queue_size = pDmxfilter->buffer.ulSize; if(pDmxfilter->flags & FILTER_FLAG_UNBUFFERED) DemuxAcq.notify_data_fn = NULL; else DemuxAcq.notify_data_fn = DemuxPESCallback; if (DemuxChannelAcquire(pGlobal,pDmxfilter,&DemuxAcq)) { printk("DemuxFilterBucketSet(): Error acquiring channel for bucket queue\n"); return(-EMFILE); } if(pDmxfilter->flags & FILTER_FLAG_UNBUFFERED) { xp_osi_interrupt_channel_notify(pGlobal, XP_INTERRUPT_NOTIFY_ADD, pDmxfilter->chid, XP_INTERRUPT_QSTAT_RPI|XP_INTERRUPT_QSTAT_BTI|XP_INTERRUPT_QSTAT_FP, (XP_INTERRUPT_CHANNEL_FN)DemuxCallback_nb); } return(0);} /*----------------------------------------------------------------------------+| DemuxFilterPESDecoderSet|| DESCRIPTION: Set the PES filter parameters when directly outputting PES| data to the Transport audio and video unloaders.+----------------------------------------------------------------------------*/static int DemuxFilterPESDecoderSet( GLOBAL_RESOURCES *pGlobal, DEMUX_FILTER *pDmxfilter){ int rc=0; UINT chid=ILLEGAL_CHANNEL; XP_CHANNEL_TYPE ctype; PDEBUG("DemuxFilterPESDecoderSet(): Entering\n"); /*----------------------------------------------------------------------------+ | Deliver Audio/video/PCR PES data to hardware decoder | Initially, allocate channel and set PID manually +----------------------------------------------------------------------------*/ if (pDmxfilter->chid == ILLEGAL_CHANNEL || pDmxfilter->states < FILTER_STAT_START) { if (pDmxfilter->states >= FILTER_STAT_SET) { if(pDmxfilter->flags & FILTER_FLAG_MMAPPED) { printk("DemuxFilterPESDecoderSet(): Error - filter is mmapped\n"); return(-1); } DemuxFilterReset(pGlobal,pDmxfilter); } pDmxfilter->type = FILTER_TYPE_PES; pDmxfilter->pid = pDmxfilter->pes_para.pid; pDmxfilter->states = FILTER_STAT_SET; switch (pDmxfilter->pes_para.pesType) { case DMX_PES_VIDEO: ctype = XP_CHANNEL_TYPE_VIDEO; chid = XP_CHANNEL_VIDEO; break; case DMX_PES_AUDIO: ctype = XP_CHANNEL_TYPE_AUDIO; chid = XP_CHANNEL_AUDIO; break; case DMX_PES_PCR: pDmxfilter->chid = 0x1001; //vitual PID return(0); break; default: printk("DemuxFilterPESDecoderSet(): Illegal PES Type\n"); return(-EINVAL); break; } os_get_mutex(hMutex); if (pDmxfilter->chid == ILLEGAL_CHANNEL) { if (xp_osi_channel_get_available(pGlobal,ctype) == 0) { xp_osi_channel_free(pGlobal,chid); } if ((rc = xp_osi_channel_allocate(pGlobal,ctype)) >= 0) { pDmxfilter->chid = rc; } else { os_release_mutex(hMutex); printk("DemuxFilterPESDecoderSet(): Error allocating PES channel\n"); return(-1); } } xp_osi_channel_set_pid(pGlobal,(short)pDmxfilter->chid, (unsigned short)pDmxfilter->pid); os_release_mutex(hMutex); } else { /*-------------------------------------------------------------------------+ | Deliver Audio/video/PCR PES data to hardware decoder using automated | channel change functions. This assumes the channel has been allocated. +-------------------------------------------------------------------------*/ pDmxfilter->type = FILTER_TYPE_PES; pDmxfilter->pid = pDmxfilter->pes_para.pid; pDmxfilter->states = FILTER_STAT_START_CC; switch (pDmxfilter->pes_para.pesType) { case DMX_PES_VIDEO: xp_osi_video_cchan_auto(pGlobal,pDmxfilter->pid); break; case DMX_PES_AUDIO: xp_osi_audio_cchan_auto(pGlobal,pDmxfilter->pid); break; case DMX_PES_PCR: xp_osi_pcr_cchan_auto(pGlobal,pDmxfilter->pid); break; default: printk("DemuxFilterPESDecoderSet(): Illegal PES Type\n"); return(-EINVAL); break; } } return(0);}/*----------------------------------------------------------------------------+| DemuxFilterPESMemorySet|| DESCRIPTION: Set the PES filter parameters when outputting PES data to| the sport queues.+----------------------------------------------------------------------------*/static int DemuxFilterPESMemorySet( GLOBAL_RESOURCES *pGlobal, DEMUX_FILTER *pDmxfilter){ DEMUX_CHANNEL_ACQUIRE_TYPE DemuxAcq; XP_CONFIG_VALUES Config; XP_CHANNEL_TYPE ctype; UINT chid=ILLEGAL_CHANNEL; PDEBUG("DemuxFilterPESMemorySet(): Entering\n"); /*----------------------------------------------------------------------------+ | Deliver PES data to Transport Queues +----------------------------------------------------------------------------*/ if (pDmxfilter->states >= FILTER_STAT_SET) { if(pDmxfilter->flags & FILTER_FLAG_MMAPPED) { printk("DemuxFilterPESMemorySet(): Error - filter is mmapped\n"); return(-1); } DemuxFilterReset(pGlobal,pDmxfilter); } pDmxfilter->type = FILTER_TYPE_PES; pDmxfilter->pid = pDmxfilter->pes_para.pid; pDmxfilter->states = FILTER_STAT_SET; switch (pDmxfilter->pes_para.pesType) { case DMX_PES_VIDEO: ctype = XP_CHANNEL_TYPE_VIDEO; chid = XP_CHANNEL_VIDEO; os_get_mutex(hMutex); xp_osi_get_config_values(pGlobal,&Config); Config.vpu = 1; //force all video packet to memory unloader xp_osi_set_config_values(pGlobal,&Config); os_release_mutex(hMutex); break; case DMX_PES_AUDIO: ctype = XP_CHANNEL_TYPE_AUDIO; chid = XP_CHANNEL_AUDIO; os_get_mutex(hMutex); xp_osi_get_config_values(pGlobal,&Config); Config.apu = 1; //force all audio packet to memory unloader xp_osi_set_config_values(pGlobal,&Config); os_release_mutex(hMutex); break; case DMX_PES_PCR: return(0); break; case DMX_PES_TELETEXT: ctype = XP_CHANNEL_TYPE_TELETEXT; chid = XP_CHANNEL_TELETEXT; break; case DMX_PES_SUBTITLE: ctype = XP_CHANNEL_TYPE_SUBTITLE; chid = XP_CHANNEL_SUBTITLE; break; case DMX_PES_OTHER: ctype = XP_CHANNEL_TYPE_PES; chid = ILLEGAL_CHANNEL; break; default: printk("DemuxFilterPESMemorySet(): Illegal PES Type\n"); return(-EINVAL); break; } if (pDmxfilter->chid == ILLEGAL_CHANNEL) { os_get_mutex(hMutex); if (xp_osi_channel_get_available(pGlobal,ctype) == 0) { xp_osi_channel_free(pGlobal,chid); } os_release_mutex(hMutex); DemuxAcq.channel_type = ctype; DemuxAcq.pid = pDmxfilter->pid; DemuxAcq.unload_type = pDmxfilter->pes_para.unloader.unloader_type; DemuxAcq.bthreshold = pDmxfilter->pes_para.unloader.threshold; if(pDmxfilter->flags & FILTER_FLAG_UNBUFFERED) DemuxAcq.notify_data_fn = NULL; else DemuxAcq.notify_data_fn = DemuxPESCallback; DemuxAcq.queue_size = 0; if (pDmxfilter->pes_para.output == OUT_MEMORY) { DemuxAcq.queue_size = pDmxfilter->buffer.ulSize; } if (DemuxChannelAcquire(pGlobal,pDmxfilter,&DemuxAcq)) { printk("DemuxFilterPESMemorySet(): Error allocating PES channel\n"); return(-EMFILE); } if(pDmxfilter->flags & FILTER_FLAG_UNBUFFERED) { xp_osi_interrupt_channel_notify(pGlobal, XP_INTERRUPT_NOTIFY_ADD, pDmxfilter->chid, XP_INTERRUPT_QSTAT_RPI | XP_INTERRUPT_QSTAT_BTI, (XP_INTERRUPT_CHANNEL_FN)DemuxCallback_nb); } } else { os_get_mutex(hMutex); xp_osi_channel_set_pid(pGlobal,(short)pDmxfilter->chid, (unsigned short)pDmxfilter->pid); os_release_mutex(hMutex); } return(0);}/*----------------------------------------------------------------------------+| DemuxFilterTSSet|| DESCRIPTION: Set the TS out mode+----------------------------------------------------------------------------*/static int DemuxFilterTSSet( GLOBAL_RESOURCES *pGlobal, DEMUX_FILTER *pDmxfilter){ DEMUX_CHANNEL_ACQUIRE_TYPE DemuxAcq; PDEBUG("DemuxFilterTSSet(): Entering\n"); if(pDmxfilter->pDemuxDev->users > 1) { printk("DemuxFilterTSSet(): Error - Too many filters opened!\n"); return(-1); } if (pDmxfilter->states >= FILTER_STAT_SET) { if(pDmxfilter->flags & FILTER_FLAG_MMAPPED) { printk("DemuxFilterTSSet(): Error - filter is mmapped\n"); return(-1); } DemuxFilterReset(pGlobal,pDmxfilter); } pDmxfilter->type = FILTER_TYPE_TS; pDmxfilter->states = FILTER_STAT_SET; xp_osi_set_parse_bypass_mode(pGlobal); /*----------------------------------------------------------------------------+ | Allocate Channel for Transport Stream +----------------------------------------------------------------------------*/ DemuxAcq.channel_type = XP_CHANNEL_TYPE_SUBTITLE; DemuxAcq.pid = XP_CHANNEL_NULL_PID; DemuxAcq.unload_type = XP_CHANNEL_UNLOAD_TRANSPORT; DemuxAcq.bthreshold = 255; DemuxAcq.queue_size = pDmxfilter->buffer.ulSize; if(pDmxfilter->flags & FILTER_FLAG_UNBUFFERED) DemuxAcq.notify_data_fn = NULL; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -