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

📄 hwlprivate.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************** Copyright (c) 2002 Sigma Designs Inc. All rights reserved. ********************************************************************//*  @file   hwlprivate.c  See licensing details in LICENSING file  */// pch from HWL#include "pch.h"#include "registry.h"#include "regs840x.h"#include "common.h"#include "cqsrbrd.h"// debugunsigned long hw_video_byte_counter;unsigned long hw_audio_byte_counter;//// ac3 frame sizeDWORD frmsizecod_table[4][38] = {	// 48	{64, 64, 80, 80, 96, 96, 112, 112, 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 	384, 384, 448, 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152, 1152, 1280, 1280},	// 44.1	{69, 70, 87, 88, 104, 105, 121, 122, 139, 140, 174, 175, 208, 209, 243, 244, 278, 279, 348, 349,	417, 418, 487, 488, 557, 558, 696, 697, 835, 836, 975, 976, 1114, 1115, 1253, 1254, 1393, 1394},	// 32	{96, 96, 120, 120, 144, 144, 168, 168, 192, 192, 240, 240, 288, 288, 336, 336, 384, 384, 480, 480,	576, 576, 672, 672, 768, 768, 960, 960, 1152, 1152, 1344, 1344, 1536, 1536, 1728, 1728, 1920, 1920},	//reserved - default to 48	{64, 64, 80, 80, 96, 96, 112, 112, 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 	384, 384, 448, 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152, 1152, 1280, 1280},};//#define VERBOSE 1//#define VERBOSE_2 1//XXX#define MPEG_IRQMASK	(CC_INTERRUPT | VSYNC_INTERRUPT | AUDIO_FIFO_THRESHOLD | VIDEO_FIFO_THRESHOLD | VIDEO_END_OF_SEQUENCE | OSD_INTERRUPT)////// FIXME#define INTENA_REG (*(volatile int *)0x00500224)#define INTPOL_REG (*(volatile int *)0x00500220)static inline void disable_quasar_irq(){	int reg;	reg = INTENA_REG;	reg &= ~(1<<QUASAR_IRQ(&Q));	INTENA_REG = reg;	}static inline void enable_quasar_irq(){	int reg;	reg = INTENA_REG;	reg |= (1<<QUASAR_IRQ(&Q));	INTENA_REG = reg;	}// Lock and Unlock Quasar Interrupts#define QLOCK() disable_quasar_irq();#define QUNLOCK() enable_quasar_irq();/////// static feedpacket *getFeedPacket(FeedPacketQ *pQ){#ifdef VERBOSE//	if(pQ->pFirstPacket)//		pQprintk("getFeedPacket: Q=%p packet = %p\n",pQ, pQ->pFirstPacket);#endif	return pQ->pFirstPacket;}static void nextFeedPacket(FeedPacketQ *pQ){	feedpacket *pP=pQ->pFirstPacket;#ifdef VERBOSE	if(pP)		pQprintk("nextFeedPacket: Q=%p, packet = %p\n",pQ,pP);#endif	// Used Q is empty do nothing	if(pP==NULL) {#ifdef VERBOSE		pQprintk("Q %p is empty\n",pQ);#endif		return;	}	// advance Used Q to next	pQ->pFirstPacket=pP->pNext;#ifdef QUEUES_STAT	pQ->nb--;	pQ->nb_out++;	pFreeQ->nb++;	pFreeQ->nb_in++;#endif	// Used Q is empty now ?	if(pP->pNext==NULL) {#ifdef VERBOSE		pQprintk("Last packet in Q %p\n",pQ);#endif		pQ->pLastPacket=NULL;	}	// Free Q is empty ?	if((pFreeQ->pLastPacket)==NULL) 		pFreeQ->pFirstPacket=pP;	else		pFreeQ->pLastPacket->pNext=pP;	pFreeQ->pLastPacket=pP;	pP->pNext=NULL;}//int apts_counter = 0;//int vpts_counter = 0;static void hwlprivate_tophalf(int irq, void *dev_t, struct pt_regs * regs){	/* THIS FUNCTION IS TIME CRITICAL AND FREEZES THE PC	   UNTIL IT RETURNS.	  	   Don't access user space (we are not called from a process)	   Don't call schedule()	   Don't sleep	   Don't kmalloc anything else than GFP_ATOMIC	   Don't use semaphores.	   We should:	   "Do the fewest things possible. 	   Implement everything else in hwlprivate_tasklet."	   But we don't! It shouldnt be a problem for Jasper DVD player.	   Sorry Manu :) - Fabrice	*/	struct quasarprivate *pQ=(struct quasarprivate *)dev_t;	int osd_image_completed;	DWORD IrqStatus;	feedpacket *pP;#if 0//XXX REMOVE	if(pQ->H.pIDecoderBoard->lpVtbl == NULL ) {		pQprintk("Error : IDecoderBaord->lpVtbl is NULL\n");	        asm(".long 0x66727473\n");		return;	}//XXX REMOVE	if(irq!=21)		pQprintk("ERORR the IRQ is not 21!!\n");#endif    // shared irq case: we return - shouldnt happen with JASPER.    if (IDecoderBoard_IsIntActive(pQ->H.pIDecoderBoard,&IrqStatus)==FALSE)	{		printk ("hwl_tophalf: Spurious IRQ - is it shared??\n"			 "pIDecoderBoard = %p\n&IsIntActive = %p)\n",			 pQ->H.pIDecoderBoard,			 pQ->H.pIDecoderBoard->lpVtbl->IsIntActive);				return;	}#ifdef VERBOSE//	pQprintk("Received Quasar interrupt: status = %08x\n",IrqStatus);#endif	if (IrqStatus & CC_INTERRUPT)		IDecoderBoard_CloseCaptionInterrupt (pQ->H.pIDecoderBoard, 0);	if (IrqStatus & VIDEO_END_OF_SEQUENCE) {		//printk ("!!!!! VIDEO_END_OF_SEQUENCE: %d\n", pQ->out_display_option);		if (pQ->out_display_option == evOutDisplayOption_16x9to4x3_PanScan)		{			CQuasar *this = (CQuasar*)pQ->H.pIDecoder;			Q4SymbolTable *pQ4 = (Q4SymbolTable*)this->pQ;			if (pQ4)			{				//printk ("!!!!! set to 540\n");				IDecoder_WriteDM (pQ->H.pIDecoder, pQ4->DisplayHorSize.addr, 540);			}		}	}/*	if (IrqStatus & VIDEO_EVENT_PAUSE) {		printk ("VIDEO_EVENT_PAUSE\n");		IDecoderBoard_VideoHwPause (pQ->H.pIDecoderBoard);	}*//*		if (IrqStatus & VIDEO_FIFO_THRESHOLD) {		if (pQ->callingProcessPid!=0)			kill_proc(pQ->callingProcessPid,SIGUSR2,0);	}		if (IrqStatus & AUDIO_FIFO_THRESHOLD) {		if (pQ->callingProcessPid!=0)			kill_proc(pQ->callingProcessPid,SIGUSR2,0);	}*/#if 0	if (IrqStatus & (VIDEO_FIFO_THRESHOLD | AUDIO_FIFO_THRESHOLD /*| VSYNC_INTERRUPT*/)) 	{		feedpacket *pP;		DATA_FIFO vfifo, afifo;/*		if ((IrqStatus & AUDIO_FIFO_THRESHOLD) && (pQ->H.AudioByteCounter > 1000000))		{			IDecoderBoard_GetDataFifoInfo (pQ->H.pIDecoderBoard, AUDIO, &afifo);			if (getFeedPacket(pAudioQ) == NULL)				printk ("***** (PRE) audioQ is empty!\n");		}		if ((IrqStatus & VIDEO_FIFO_THRESHOLD) && (pQ->H.VideoByteCounter > 3000000))		{			IDecoderBoard_GetDataFifoInfo (pQ->H.pIDecoderBoard, VIDEO, &vfifo);			if (getFeedPacket(pVideoQ) == NULL)				printk ("***** (PRE) videoQ is empty!\n");		}*/		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, VIDEO, &pQ->H.VideoEventPending);		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, AUDIO, &pQ->H.AudioEventPending);		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, SPU, &pQ->H.SpuEventPending);		// Try to send all Q'ed packets		while(((pP=getFeedPacket(pVideoQ))!=NULL) 		      && (hwlprivate_feedme(pQ,pP)==0))			nextFeedPacket(pVideoQ);		while(((pP=getFeedPacket(pAudioQ))!=NULL)		      && (hwlprivate_feedme(pQ,pP)==0))			nextFeedPacket(pAudioQ);		while(((pP=getFeedPacket(pSpuQ))!=NULL)		      && (hwlprivate_feedme(pQ,pP)==0))			nextFeedPacket(pSpuQ);				if (1)		{						IDecoderBoard_GetDataFifoInfo (pQ->H.pIDecoderBoard, VIDEO, &vfifo);			IDecoderBoard_GetDataFifoInfo (pQ->H.pIDecoderBoard, AUDIO, &afifo);			if ((vfifo.Fullness == 0) || (afifo.Fullness == 0))			{				if (pQ->H.AudioByteCounter && (getFeedPacket(pAudioQ) == NULL))				{					printk ("***** (POST) audioQ is empty! (%d)\n", (int)afifo.Fullness);				}				if (pQ->H.VideoByteCounter && (getFeedPacket(pVideoQ) == NULL))				{					printk ("***** (POST) videoQ is empty! (%d)\n", (int)vfifo.Fullness);				}			}		}	}#endif	pQ->interrupt_counter++;	// update read/write pointers	if (IrqStatus & VSYNC_INTERRUPT)	{		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, VIDEO, &pQ->H.VideoEventPending);		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, AUDIO, &pQ->H.AudioEventPending);		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, SUBPICTURE, &pQ->H.SpuEventPending);		IDecoderBoard_FreeConsumedData (pQ->H.pIDecoderBoard, OSD, &pQ->H.OsdEventPending);		while(((pP=getFeedPacket(pSpuQ))!=NULL)		      && (hwlprivate_feedme(pQ,pP)==0))			nextFeedPacket(pSpuQ);	}	if (IrqStatus & VIDEO_FIFO_THRESHOLD)	{		while(((pP=getFeedPacket(pVideoQ))!=NULL) 		      && (hwlprivate_feedme(pQ,pP)==0))			nextFeedPacket(pVideoQ);	}	if (IrqStatus & AUDIO_FIFO_THRESHOLD)	{		while(((pP=getFeedPacket(pAudioQ))!=NULL)		      && (hwlprivate_feedme(pQ,pP)==0))			nextFeedPacket(pAudioQ);	}	// XXX vincent - must call refresh all the time	// when we are paused, the threshold interrupts will not come	osd_image_completed = 0;	if (IrqStatus & VSYNC_INTERRUPT)	{		// automatic refresh		if (pQ->O.active)		{						osd_image_completed = osdfb_refresh (pQ);		} 		else 		{			osd_image_completed = 1;		}		// manual refresh		if (pQ->H.osd_wait && pQ->H.osdleft)		{			int xfer;			MPEG_WRITE_DATA MWD;			BOOL rc;			while (1)			{				MWD.pOverlapped = 0;				MWD.pPacketList = 0;				MWD.uiPacketCount = 0;				MWD.uiPacketIndex = 0;				MWD.pData = pQ->H.posd;				xfer = min ((int)pQ->H.osdleft, (int)0xf000);				rc = IDecoderBoard_SendOSDPayload (pQ->H.pIDecoderBoard, 					&MWD, (unsigned long)xfer, 0, 0, &pQ->H.OsdByteCounter, &pQ->H.OsdEventPending);				if (rc == TRUE)				{					pQ->H.posd += xfer;					pQ->H.osdleft -= xfer;				}				else					break;			}		}	}	if (IrqStatus & OSD_INTERRUPT)	{				if (pQ->H.osd_wait)		{			ASSERT (pQ->H.osdleft == 0);			complete (pQ->H.osd_wait);			pQ->H.osd_wait = 0;		}	}		if (osd_image_completed)	{		// this means that one osd picture has been sent		// complete any pending SetProperty commands		if (pQ->destination_pending)		{//			printk ("(%d %d %d %d)\n",//				pQ->destination_wnd.x,//				pQ->destination_wnd.y,//				pQ->destination_wnd.w,//				pQ->destination_wnd.h);			IDecoderBoard_SetProperty (				pQ->H.pIDecoderBoard, 				VIDEO_SET, evDestinationWindow, 0, 				&pQ->destination_wnd, sizeof(pQ->destination_wnd), 0);			pQ->destination_pending = 0;		}		if (pQ->aspect_pending)		{			IDecoderBoard_SetProperty (				pQ->H.pIDecoderBoard, 				VIDEO_SET, evInAspectRatio, 0, 				&pQ->in_aspect_ratio, sizeof(pQ->in_aspect_ratio), 0);			pQ->aspect_pending = 0;		}		if (pQ->display_pending)		{			IDecoderBoard_SetProperty (				pQ->H.pIDecoderBoard, 				VIDEO_SET, evOutDisplayOption, 0, 				&pQ->out_display_option, sizeof(pQ->out_display_option), 0);			pQ->display_pending = 0;		}		if (pQ->osd_destination_pending)		{			IDecoderBoard_SetProperty (				pQ->H.pIDecoderBoard, 				OSD_SET, eOsdDestinationWindow, 0, 				&pQ->osd_destination_wnd, sizeof(pQ->osd_destination_wnd), 0);			pQ->osd_destination_pending = 0;		}		if (pQ->forced_progressive_pending)		{						IDecoderBoard_SetProperty (				pQ->H.pIDecoderBoard, 				VIDEO_SET, evForcedProgressiveAlways, 0, 				&pQ->forced_progressive, sizeof(pQ->forced_progressive), 0);			pQ->forced_progressive_pending = 0;		}		if (pQ->play_pending)		{			DWORD vr, vl, v;			if ((PLAY_OPTIONS)pQ->play_mode != VideoHwPlayToEvent)			{				IDecoderBoard_AudioHwPlay(pQ->H.pIDecoderBoard);			}						IDecoderBoard_VideoHwPlay(pQ->H.pIDecoderBoard, (PLAY_OPTIONS)(pQ->play_mode), 1);			pQ->play_pending = 0;				// XXX vincent: patch to unmute the audio			//              sometimes the audio gain register is muted after a PLAY?			v = IDecoder_ReadReg (pQ->H.pIDecoder, 0x1FD7);			vr = IDecoder_GetVolumeRight (pQ->H.pIDecoder);			vl = IDecoder_GetVolumeLeft (pQ->H.pIDecoder);			if ((v == 0) && (vr || vl))			{#ifdef VERBOSE				//XXX				pQprintk("[%d]Warning: audio muted... unmuting!!!\n", (int)pQ->interrupt_counter);#endif				IDecoder_SetVolumeRight (pQ->H.pIDecoder, vr);				IDecoder_SetVolumeLeft (pQ->H.pIDecoder, vl);			} else {#ifdef VERBOSE				pQprintk("[%d]Warning: audio not muted... OK!!!\n", pQ->interrupt_counter);#endif			}		}	}	//XXX audio auto mute counter measures	// sometime the audio gain register goes mute	{		DWORD vr, vl, v;		v = IDecoder_ReadReg (pQ->H.pIDecoder, 0x1FD7);		vr = IDecoder_GetVolumeRight (pQ->H.pIDecoder);

⌨️ 快捷键说明

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