⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwlprivate.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 4 页
字号:
				unsigned short ptshi, ptslo;				CQuasar *this = (CQuasar*)pQ->H.pIDecoder;				Q4SymbolTable *pQ4 = (Q4SymbolTable*)this->pQ;				// give some extra time for buffering				pts = pMWD->Pts;				if (((pts - scr) < 20000) && scr > 20000)					scr -= 20000;//				printk ("scr: 0x%08lx%08lx pts: 0x%08lx%08lx (%d)\n", //					(DWORD)(scr>>32), (DWORD)(scr),//					(DWORD)(pts>>32), (DWORD)(pts),//					(long)(pts - scr));//				printk ("vobu start ptm: 0x%08lx%08lx\n",//					(DWORD)(pP->vobu_sptm >> 32),//					(DWORD)(pP->vobu_sptm));				// in case there is not a pts for every frame				// this will allow the ucode to calculate the pts correctly 				// for the first frame				pP->vobu_sptm -= 6006;				ptshi = (unsigned short)((pP->vobu_sptm >> 1) >> 16);				ptslo = (unsigned short)((pP->vobu_sptm >> 1) & 0xFFFF);				IDecoder_WriteDM (pQ->H.pIDecoder, pQ4->PicPTSLo.addr, ptslo);				IDecoder_WriteDM (pQ->H.pIDecoder, pQ4->PicPTSHi.addr, ptshi);							}			if (pP->flags & CTS_AVAILABLE_FLAG) {				scr = scr<<1;			}//			printk ("IDecoder_WriteSCR: %08lx\n", (unsigned long)(scr >> 1));			IDecoder_WriteSCR (pQ->H.pIDecoder, scr);			pQ->H.SetSTC = 0;		}		rc=(IDecoderBoard_SendVideoPayload(pQ->H.pIDecoderBoard,						   pMWD, 						   pP->packet.DataLeft, 						   pP->flags,						   1,/*bLastPacket: value has meaning here. F.G*/						   &pQ->H.VideoByteCounter, 						   &pQ->H.VideoEventPending)==TRUE)?0:-1;		if (rc==0){//			if (pP->flags)//				printk ("vpts: %08lx (%d)\n", (unsigned long)(pP->packet.Pts >> 1), (int)pP->packet.DataLeft);			pQ->H.VideoEventPending++; //		printk ("pQ->H.VideoByteCounter = %d\n", (int)pQ->H.VideoByteCounter);#ifdef VERBOSE				pQprintk("hwlprivate_feedme:[VIDEO] pP=%p, MWD=%p\n",pP,pMWD);#endif			if (pP->flags)			{				pQ->last_video_pts_sent = (unsigned long)(pMWD->Pts >> 1);				pQ->scr_when_last_video_pts_was_sent = (unsigned long)(IDecoder_ReadSCR (pQ->H.pIDecoder) >> 1);			}			/*			if (pP->flags)			{				if (++vpts_counter > 10)				{					unsigned long long pts, scr;					vpts_counter = 0;					pts = pMWD->Pts;					scr = IDecoder_ReadSCR (pQ->H.pIDecoder);					printk ("vpts: 0x%02lx%08lx, scr: 0x%02lx%08lx, bytecounter: %lu, (%ld)\n",						(unsigned long)(pts >> 32), (unsigned long)(pts),						(unsigned long)(scr >> 32), (unsigned long)(scr),						(unsigned long)pQ->H.VideoByteCounter,						(long)(pts - scr));				}			}			*/		}#ifdef VERBOSE		else {			DWORD a,v;//			//			pQprintk("Cant send VIDEO\n");			v=IDecoder_GetStatus(pQ->H.pIDecoder,VIDEO);			a=IDecoder_GetStatus(pQ->H.pIDecoder,AUDIO);			pQprintk("Audio = %ld, Video = %ld\n",a,v);		}#endif		return rc;		break;			case AUDIO:		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, AUDIO, &pQ->H.AudioEventPending);//		IDecoder_GetDataFifoInfo (pQ->H.pIDecoder, AUDIO, &datafifo);//		if (datafifo.Emptiness < pP->packet.DataLeft)//			return -1;//		if (IDecoder_PacketsFifoEmptiness (pQ->H.pIDecoder, AUDIO) <= 35)//			return -1;		if (pP->flags)		{			// ``1'' means the PTS fifo is full. Not to be confused with audio payload fifo.			if (IDecoderBoard_PtsFifoEmptiness(pQ->H.pIDecoderBoard,AUDIO)<=1) {//				printk ("audio pts fifo full\n");				return -1;			}		}#if 1//		printk ("(%d)\n", pMWD->FirstAccessUnitPointer);//		if (pQ->H.AudioByteCounter == 0)//		{//			printk ("audio PTS when bytecounter=0 is %08lx\n",//				pMWD->Pts);//		}			if ((pQ->H.AudioByteCounter == 0) && pP->scr && pP->flags)		{			long delta;			unsigned long long scr, pts;			scr = IDecoder_ReadSCR (pQ->H.pIDecoder);			pts = pMWD->Pts & 0x1ffffffffll;			if(pP->flags & CTS_AVAILABLE_FLAG) {				scr = scr>>1;			}			delta = pts - scr;//			printk ("(scr=%08lx, pts=%08lx)\n", (unsigned long)(scr>>1), (unsigned long)(pMWD->Pts>>1));			if (delta > 0)			{				rc = -1;			}			else			{				pP->flags = 0;//				printk ("audio pts0 = %08lx, scr = %08lx\n", (unsigned long)(pMWD->Pts>>1), (unsigned long)(scr>>1));				rc=(IDecoderBoard_SendAudioPayload(pQ->H.pIDecoderBoard, 								   pMWD,								   pP->packet.DataLeft, 								   pP->flags,								   1,/*bLastPacket: value has meaning here. F.G*/								   &pQ->H.AudioByteCounter, 								   &pQ->H.AudioEventPending)==TRUE)?0:-1;			}		}		else		{			int pts_modified;			long long original_pts = 0;			pts_modified = 0;			if ((pQ->H.eAudioFormat_value == AUDIO_FORMAT_AC3) &&				(pQ->H.eAudioDigitalOutput_value == AUDIO_OUTPUT_STEREO) &&				(pQ->H.pts_delay_valid == 0))			{												unsigned long ac3_status_lo, ac3_status_hi, fscod, frmsizcod;								ac3_status_lo = IDecoder_ReadReg (pQ->H.pIDecoder, AUDIO_ac3_status_lo);				ac3_status_hi = IDecoder_ReadReg (pQ->H.pIDecoder, AUDIO_ac3_status_hi);				fscod = (ac3_status_lo >> 10) & 0x3;				frmsizcod = (ac3_status_lo >>  4) & 0x3f; //				printk ("fscod: %02x, frmsizcod: %02x\n",//					fscod, frmsizcod);				if ((fscod <=3) && (frmsizcod < 38) && (ac3_status_hi & 0x8000))				{					if (pP->flags)					{						int bytecounter_offset;						if (pP->flags & PTS_AVAILABLE_FLAG)						{							// XXX assume 48kHz							pQ->H.pts_delay = (512*4) / frmsizecod_table[fscod][frmsizcod] * 2880;						}						else						{															unsigned long timescale;							IDecoderBoard_GetProperty (pQ->H.pIDecoderBoard,								TIME_SET, etimAudioCTSTimeScale, 0, 								&timescale, sizeof(timescale), NULL);//							printk ("audioctstimescale = %d\n", (int)timescale);							// (256*6/frequency) * timescale = time for 1 ac3 frame							if (fscod == 1)							{								// 44.1khz								pQ->H.pts_delay = (512*4) / frmsizecod_table[fscod][frmsizcod] * (timescale*384/11025);							}							else if (fscod == 2)							{								// 32khz								pQ->H.pts_delay = (512*4) / frmsizecod_table[fscod][frmsizcod] * (timescale*6/125);							}							else							{								// 48khz								pQ->H.pts_delay = (512*4) / frmsizecod_table[fscod][frmsizcod] * (timescale*4/125);							}						}												bytecounter_offset = (int)(frmsizecod_table[fscod][frmsizcod] << 1);						bytecounter_offset = bytecounter_offset - (4096 % bytecounter_offset);						if (pQ->H.AudioByteCounter > bytecounter_offset)						{																			pQ->H.pts_delay_valid = 1;							if (pMWD->FirstAccessUnitPointer)							{								pQ->H.pts_delay = 0;								pQ->H.AudioByteCounter -= bytecounter_offset;								//printk ("bytecounter_offset: %d\n", bytecounter_offset);							}						}						//printk ("ac3 frame length: %d, delay: %d\n", (int)(frmsizecod_table[fscod][frmsizcod] << 1), pQ->H.pts_delay);					}				}						 				pP->flags = 0;			}			else if (pP->flags)			{				pts_modified = 1;				original_pts = pMWD->Pts;				if (pQ->H.pts_delay_valid)					pMWD->Pts -= pQ->H.pts_delay;			}			rc=(IDecoderBoard_SendAudioPayload(pQ->H.pIDecoderBoard, 							   pMWD,							   pP->packet.DataLeft, 							   pP->flags,							   1,/*bLastPacket: value has meaning here. F.G*/							   &pQ->H.AudioByteCounter, 							   &pQ->H.AudioEventPending)==TRUE)?0:-1;			if (pts_modified)				pMWD->Pts = original_pts;		}#else		rc = 0;		OSCompleteIo (0,pP->packet.pOverlapped);#endif		if (rc==0){			pQ->H.AudioEventPending++; #ifdef VERBOSE					pQprintk("hwlprivate_feedme:[AUDIO] pP=%p, MWD=%p\n",pP,pMWD);#endif			if (pP->flags)			{				pQ->last_audio_pts_sent = (unsigned long)(pMWD->Pts >> 1);				pQ->scr_when_last_audio_pts_was_sent = (unsigned long)(IDecoder_ReadSCR (pQ->H.pIDecoder) >> 1);			}			/*			if (pP->flags)			{				if (++apts_counter > 20)				{					unsigned long long pts, scr;					apts_counter = 0;					pts = pMWD->Pts;					scr = IDecoder_ReadSCR (pQ->H.pIDecoder);					printk (" apts: 0x%02lx%08lx, scr: 0x%02lx%08lx, bytecounter: %lu, (%ld)\n",						(unsigned long)(pts >> 32), (unsigned long)(pts),						(unsigned long)(scr >> 32), (unsigned long)(scr),						(unsigned long)pQ->H.AudioByteCounter,						(long)(pts - scr));				}			}			*/		} 		return rc;		break;	case SPU:		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, SPU, &pQ->H.SpuEventPending);		// need to send all spu pts's or else bad things may happen		// (Men in Black director's commentary)		if (IDecoderBoard_PtsFifoEmptiness(pQ->H.pIDecoderBoard,SPU)==1)			return -1;				rc=(IDecoderBoard_SendSpuPayload(pQ->H.pIDecoderBoard, 						   pMWD, 						   pP->packet.DataLeft, 						   pP->flags,						   1,/*bLastPacket: value has meaning here. F.G*/						   &pQ->H.SpuByteCounter, 						   &pQ->H.SpuEventPending)==TRUE)?0:-1;		if (rc==0){			pQ->H.SpuEventPending++; #ifdef VERBOSE			pQprintk("hwlprivate_feedme:[SPU] pP=%p, MWD=%p\n",pP,pMWD);#endif		}		return rc;		break;			case OSD:		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, OSD, &pQ->H.OsdEventPending);		rc=(IDecoderBoard_SendOSDPayload(pQ->H.pIDecoderBoard, 						   pMWD, 						   pP->packet.DataLeft, 						   pP->flags,						   1,/*bLastPacket: value has meaning here. F.G*/						   &pQ->H.OsdByteCounter, 						   &pQ->H.OsdEventPending)==TRUE)?0:-1;		if (rc==0){			pQ->H.OsdEventPending++; #ifdef VERBOSE			pQprintk("hwlprivate_feedme:[OSD] pP=%p, MWD=%p\n",pP,pMWD);#endif		}		return rc;		break;			default:		pQprintk("hwlprivate_feedme: [UNKNOWN] pP=%p, MWD=%p\n",pP,pMWD);		break;	}	return -1;}void hwlprivate_happeningwait(struct quasarprivate *pQ,waitable *h){	long timeout_jiffies=(unsigned long long)h->timeout_microsecond*(unsigned long long)HZ/1000000ULL;	unsigned long targets;		targets=h->mask&pQ->happening;	while (1) {		if (targets) {			/* clear them. This induces problems when multiple			   processes are waiting on the same bits, a situation to avoid. */			pQ->happening=pQ->happening&(~targets);			h->mask=targets;//			pQprintk("hwlprivate_happeningwait: returning 0x%08lx to %d, happening is now 0x%08lx\n",targets,current->pid,pQ->happening);			return;		}				timeout_jiffies=interruptible_sleep_on_timeout(&pQ->happening_queue,timeout_jiffies);			// handle signals gently (esp. Control-C...)		if ((timeout_jiffies==0)||signal_pending(current)) break;				targets=h->mask&pQ->happening;	}	if (timeout_jiffies!=0) pQprintk("hwlprivate_happeningwait: signal pending\n");//	pQprintk("hwlprivate_happeningwait: did not see 0x%08lx, saying timeout to %d\n",h->mask,current->pid);	h->mask=0;}int hwlprivate_setproperty(struct quasarprivate *pQ,decoderproperty *pDp){	int rc=-EINVAL;//	pQprintk("hwlprivate_setproperty: begun (set %ld,%ld=%p...)\n",pDp->PropSet,pDp->PropId,pDp->pValue);	// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX	// we pend the setting of these properties until a complete osd image is 	// sent.  if we do not do this, we get random osd corruption when this 	// property is set.	if ((pDp->PropSet == VIDEO_SET) && (pDp->PropId == evDestinationWindow))	{		QLOCK ();		pQ->destination_pending = 1;		memcpy (&pQ->destination_wnd, pDp->pValue, sizeof(pQ->destination_wnd));		QUNLOCK ();		return 0;	}	if ((pDp->PropSet == VIDEO_SET) && (pDp->PropId == evInAspectRatio))		{		QLOCK ();		pQ->aspect_pending = 1;		memcpy (&pQ->in_aspect_ratio, pDp->pValue, sizeof(pQ->in_aspect_ratio));		QUNLOCK ();		return 0;	}	if ((pDp->PropSet == VIDEO_SET) && (pDp->PropId == evOutDisplayOption))	{		CQuasar *this = (CQuasar*)pQ->H.pIDecoder;		Q4SymbolTable *pQ4 = (Q4SymbolTable*)this->pQ;		QLOCK ();		pQ->display_pending = 1;		// init pan scan display (some dvds do not have this information,		// so we should init it - patch to fix "bad" dvds - eg. Erin Brokovich		// region 2 - danish version)		IDecoder_WriteDM (pQ->H.pIDecoder, pQ4->DisplayHorSize.addr, 540);		memcpy (&pQ->out_display_option, pDp->pValue, sizeof(pQ->out_display_option));		QUNLOCK ();		return 0;	}	if ((pDp->PropSet == OSD_SET) && (pDp->PropId == eOsdDestinationWindow))	{		QLOCK ();		pQ->osd_destination_pending = 1;		memcpy (&pQ->osd_destination_wnd, pDp->pValue, sizeof(pQ->osd_destination_wnd));		QUNLOCK ();		return 0;	}	if ((pDp->PropSet == VIDEO_SET) && (pDp->PropId == evForcedProgressiveAlways))	{		QLOCK ();		pQ->forced_progressive_pending = 1;		pQ->forced_progressive = *((int *)pDp->pValue);		QUNLOCK ();		return 0;	}	if ((pDp->PropSet == DECODER_SET) && (pDp->PropId == edecVideoStd))	{		QLOCK ();		if (*((int *)pDp->pValue))			pQ->H.is_mpeg4 = 1;		else			pQ->H.is_mpeg4 = 0;		QUNLOCK ();	}	// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX	// it seems that after you set the hdtv parameters (evCustomHdtvParams)	// you can never go back to tv mode using properties	// here is a hack to allow this	// XXX see with aurelia	if ((pDp->PropSet == VIDEO_SET) && (pDp->PropId == evOutputDevice))	{		evOutputDevice_type	*pOutputDevice = (evOutputDevice_type *)pDp->pValue;		if (*pOutputDevice == evOutputDevice_TV)		{			QLOCK ();			IDecoderBoard_SetCustomTvHdtv (pQ->H.pIDecoderBoard, 0, 0);			QUNLOCK ();		}	}	QLOCK ();	rc=(IDecoderBoard_SetProperty(pQ->H.pIDecoderBoard,pDp->PropSet,pDp->PropId,0,pDp->pValue,pDp->PropTypeLength,NULL)==Q_OK)?0:-1;	QUNLOCK ();	if ((pDp->PropSet==AUDIO_SET) && (pDp->PropId==eAudioFormat)) 		pQ->H.eAudioFormat_value=*(unsigned long *)pDp->pValue;	if ((pDp->PropSet==AUDIO_SET) && (pDp->PropId==eAudioDigitalOutput)) 		pQ->H.eAudioDigitalOutput_value=*(unsigned long *)pDp->pValue;	//	pQprintk("hwlprivate_setproperty: done (rc=%d)\n",rc);	return rc;}int hwlprivate_getproperty(struct quasarprivate *pQ,decoderproperty *pDp){	int rc=-EINVAL;	// avoid logging here; people use getproperty to monitor and get here often ;-)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -