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

📄 mpgplay.cpp

📁 EM8511s中使用的mpg播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// simple program to demonstrate mpeg playback// supports mpeg-1 system and mpeg-2 program streams#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/time.h>#include <sys/ipc.h>#include <sys/msg.h>#include <sys/wait.h>#include <malloc.h>#include "mpgparse/mpgparse.h"#include "mpegdec/mpegdec.h"#include "mpegdec/em85xx.h"#include "realmagichwl.h"#include "jasperlib.h"#include "mpegdec/myfont.c"#ifdef SUPPORT_IR#include "../ir/ir_ioctl.h"#endif#if 1static void debug_break (void){}#define ASSERT(exp)					((void)((exp)?1:(printf ("***ASSERT failed: line %d, file %s\n", __LINE__,__FILE__), debug_break(), 0)))#define DEBUGMSG(cond,printf_exp)	((void)((cond)?(printf printf_exp),1:0))#else#define ASSERT(exp)#define DEBUGMSG(cond,printf_exp)#endif// global data buffers#define NBUFFERS		(32)#define BUFFERSIZE		(64*1024)	// MUST be a multiple of 32kstatic RMuint32 databuffers[NBUFFERS * BUFFERSIZE/4];static BufferPool BPmpg;static RMuint32 *mpg_buffer = (databuffers);static MpegDecoder *pMpegDecoder = 0;static RMint32 iframe_only = 0;static RMint64 lastPTS = 0;static RMint32 videoFormat_mpeg12 = 1;static RMint64 mpeg4TimeScale = 60;// change for your remote control#define PLAY_SCANCODE		0xe817e608#define FF_SCANCODE			0xaf50e608#define FR_SCANCODE			0xa758e608//////// keyboard input#include <sys/time.h>#include <termios.h>static struct termios tio_save;static unsigned long init_count = 0;static void open_input(void){	struct termios tio;		if (init_count++) return;	if (tcgetattr(STDIN_FILENO, &tio_save) < 0) {		init_count--;		return;	}	tio = tio_save;	if (0) {		tio.c_lflag &= ~(ECHO | ICANON | ISIG);		tio.c_iflag &= ~(BRKINT);	} else {		tio.c_lflag |= (ISIG);		tio.c_lflag &= ~(ECHO | ICANON);		tio.c_iflag |= (BRKINT);		tio.c_iflag &= ~(IGNBRK);	}	tio.c_cc[VMIN] = 1;	tio.c_cc[VTIME] = 0;	tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);}static void close_input(void){	if (--init_count) return;	tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio_save);}static int available_input_key(void){	struct timeval tv;	fd_set readfds;		tv.tv_sec = 0;	tv.tv_usec = 0;	FD_ZERO(&readfds);	FD_SET(STDIN_FILENO, &readfds);	return (select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv) > 0);}static int get_input_key(char *pKey){	if (! available_input_key() )		return 0;	if (pKey == NULL)		return 0;	return (read(STDIN_FILENO, pKey, 1) == 1);}// define USE_FATFS_LIB when you want to use the sigma provided// fat file system instead of the linux one// note that the linux ide driver and fat file system must be// disabled in the kernel for the sigma fat file system to operate// correctly// #define USE_FATFS_LIB	1#ifdef USE_FATFS_LIB#include "fatfs.h"#include "ata_ioctl.h"//////////////////////////////////////////////////////////////////////// required fatfs callbacksstatic int ata_fd = -1;static RMuint32 fatfs_Ata_SendCmdRWS (	RMuint8  bDrive, RMuint8  bCmd, RMuint32 nSectorLBA, 	RMuint16 nNumSectors, RMuint8  *pbBuf, RMuint32 SizeInBytes){	RMint32		result;	ATA_COMMAND	AtaCommand;	CMD_PACKET	*pCmdPacket;	RMuint8		CmdPacket[16];	if (ata_fd == -1)	{		printf ("***Error: Ata_ReadSectorsLBA: Invalid gAtaFd. Kernel Driver not open.\n");		return (RMuint32)-1;	}	pCmdPacket = (CMD_PACKET *)&(CmdPacket[0]);	pCmdPacket->bCmd				= bCmd;	pCmdPacket->dwLBA				= nSectorLBA;	pCmdPacket->wXxLength			= nNumSectors;		// N sectors	AtaCommand.pbCmdPkt				= CmdPacket;	AtaCommand.wPacketSize			= 12;	AtaCommand.bDrv					= bDrive;	// Primary Drive	AtaCommand.pbBuffer				= pbBuf;	AtaCommand.dwRequestedXferCount	= SizeInBytes;		// SizeOf AtaCommand.pbBuffer	AtaCommand.dwActualXferCount	= 0;	AtaCommand.wAtaStatus			= 0;	AtaCommand.wAtaError			= 0;	AtaCommand.wExStatusBytes		= 0;	result = ioctl (ata_fd, ATA_IOCTL_ISSUE_ATA_COMMAND, &AtaCommand);	if (AtaCommand.wAtaError != 0) 	{		// Some Error		printf ("***Error: Ata_SendCmd(): ioctl(): AtaCommand.wAtaError = 0x%04X.\n", AtaCommand.wAtaError);	}	return ((RMuint32)AtaCommand.wAtaError);}static RMuint32 fatfs_Ata_SendCmd (	RMuint8 bDrive, RMuint8	bCmd, RMuint8 bFeature, 	RMuint8	bSectCounter, RMuint8 bSectNumber, RMuint8 bCylinderLo,	RMuint8	bCylinderHi, RMuint8 bDevHead, RMuint8 *pbIoBuf,	RMuint32 dwBufSizeInBytes){	RMint32 result;	ATA_COMMAND AtaCommand;	RMuint8 CmdPacket[16];	if (ata_fd == -1)	{		printf ("***Error: Ata_ReadSectorsLBA: Invalid gAtaFd. Kernel Driver not open.\n");		return (RMuint32)-1;	}	// Universal control - Send values for all registers + bDrv	CmdPacket[0]	= bCmd;	CmdPacket[1]	= bFeature;	CmdPacket[2]	= bSectCounter;	CmdPacket[3]	= bSectNumber;	CmdPacket[4]	= bCylinderLo;	CmdPacket[5]	= bCylinderHi;	CmdPacket[6]	= bDevHead;	AtaCommand.pbCmdPkt				= CmdPacket;	AtaCommand.wPacketSize			= 12;	AtaCommand.bDrv					= bDrive;			// Primary Drive	AtaCommand.pbBuffer				= pbIoBuf;	AtaCommand.dwRequestedXferCount	= dwBufSizeInBytes;	// SizeOf AtaCommand.pbBuffer	AtaCommand.dwActualXferCount	= 0;	AtaCommand.wAtaStatus			= 0;	AtaCommand.wAtaError			= 0;	AtaCommand.wExStatusBytes		= 0;	result = ioctl (ata_fd, ATA_IOCTL_ISSUE_ATA_COMMAND, &AtaCommand);	if (AtaCommand.wAtaError != 0) 	{		// Some Error		printf ("***Error: Ata_SendCmd(): ioctl(): AtaCommand.wAtaError = 0x%04X.\n", AtaCommand.wAtaError);	}	return( (RMuint32)AtaCommand.wAtaError );}static void *fatfs_malloc (RMuint32 s){	void *p;		p = malloc (s);	printf ("%08lx = fatfs_malloc (%d)\n", (RMuint32)p, (RMint32)s);	return p;}static void fatfs_free (void *p){	printf ("fatfs_free (%08lx)\n", (RMuint32)p);	return free (p);}#endifstatic int gettime_ms (void){	struct timeval tv1;	struct timezone tz;	gettimeofday (&tv1, &tz);	return tv1.tv_sec * 1000 + tv1.tv_usec/1000;}/////////////////////////////////////////////////////////////////////////////// filesystem callbacksstatic RMuint32 mpg_fopen (RMint8 *filename, void *context){#ifdef USE_FATFS_LIB	FATFS_ERROR fatfs_err;	RMuint32 fd = (RMuint32)INVALID_HANDLE;		fatfs_err = fatfs_fopen ((RMuint8 *)filename, _O_RDONLY, &fd);	ASSERT (fatfs_err == FATFS_ERROR_NO_ERROR);	if (fatfs_err != FATFS_ERROR_NO_ERROR)		return 0;	return fd;#else	return (RMint32)fopen (filename, "rb");#endif}static RMuint32 mpg_fread (RMuint32 handle, void *buf, RMuint32 length, void *context){#ifdef USE_FATFS_LIB	FATFS_ERROR fatfs_err;	RMuint32 n;	fatfs_err = fatfs_fread (handle, (RMuint8 *)buf, length, &n);	if (fatfs_err != FATFS_ERROR_NO_ERROR)		return 0;	return n;#else	return (RMint32)fread (buf, 1, length, (FILE *)handle);#endif}static RMuint32 mpg_fseek (RMuint32 handle, RMint32 pos, RMint32 whence, void *context){#ifdef USE_FATFS_LIB	FATFS_ERROR fatfs_err;	ASSERT (whence == SEEK_SET);	fatfs_err = fatfs_fseek (handle, pos, SEEK_SET);	if (fatfs_err != FATFS_ERROR_NO_ERROR)		return 0;	return pos;#else	return fseek ((FILE *)handle, pos, whence);#endif}static RMuint32 mpg_fclose (RMuint32 handle, void *context){#ifdef USE_FATFS_LIB	fatfs_fclose (handle);#else	return fclose ((FILE *)handle);#endif}//////////////////////////////////////////////////////////////////////////////static RMuint32 mpg_addref (RMuint8 *pBuffer, void *context){	BufferPool *BP = &BPmpg;	int idx = ((int)pBuffer - (int)BP->start_address) / BP->buffers_size;	ASSERT (idx >= 0);	addref_buffer (&(BP->B[idx]));	return 0;}static RMuint32 mpg_release (RMuint8 *pBuffer, void *context){	BufferPool *BP = &BPmpg;	int idx = ((int)pBuffer - (int)BP->start_address) / BP->buffers_size;	ASSERT (idx >= 0);	release_buffer (&(BP->B[idx]));	return 0;}static RMuint32 mpg_getMPG (RMuint8 **pBuffer, RMuint32 *plength, void *context){	int idx = find_free_buffer (&BPmpg, 0);	if (idx < 0)	{		return 1;	}	DEBUGMSG (0, ("idx = %d\n", idx));	*plength = (RMuint32)BPmpg.buffers_size;	*pBuffer = (RMuint8 *)get_buffer_address (&BPmpg, idx);	return 0;}static RMuint32 mpg_info (RMint32 msg, void *info, void *context){	return 0;}static RMuint8 videoStreamId = 0xff;static RMuint8 audioStreamId = 0xff;static RMuint8 audioSubStreamId = 0xff;static RMint32 audioFreq = 0;// you can select diffent stream ids here// in this sample implementation, the first audio/video stream// encountered are selectedRMuint32 mpg_putpayload (RMuint8 *pData, RMuint32 Length, RMuint8 StreamId, RMuint8 SubStreamId,	RMint64 Scr, RMint64 Pts, RMint64 Dts, RMuint8 Flags, void *context){		if (Flags & PTS_VALID_FLAG)		lastPTS = Pts;	if (Length == 0)		return 0;	// if a video stream has not been selected yet	if (videoStreamId == 0xff)	{		if ((StreamId & 0xf0) == 0xe0)		{			// mpeg1/2 video			videoStreamId = StreamId;			printf ("videoStreamId = %02x\n", videoStreamId);		}	}	// if an audio stream has not been selected yet	if (audioStreamId == 0xff)	{		if ((StreamId & 0xf0) == 0xc0)		{			// mpeg audio			// check sampling rate			RMuint8 *p = pData;			for (RMuint32 i=0; i<Length-3; i++)			{				// check header				if ((p[0] == 0xff) && ((p[1] & 0xf0) == 0xf0))				{					// check layer					if ((p[1] & 0x6) != 0)					{						// check bitrate index						if ((p[2] & 0xf0) != 0xf0)						{							// check sample frequency							if ((p[2] & 0xc) != 0xc)							{								RMint32 audioFreqTable[] = {44100, 48000, 32000, 44100};								// assume ok ...								audioStreamId = StreamId;								audioSubStreamId = SubStreamId;								audioFreq = audioFreqTable[(p[2] & 0xc) >> 2];								printf ("StreamId = %02x, SubStreamId = %02x, mpeg @ %d\n", audioStreamId, audioSubStreamId, audioFreq);								MPEGAUDIO_PARAMETERS mpeginfo;								mpeginfo.layer = 2;								mpeginfo.rawOutput = 0;								mpeginfo.SamplesPerSecond = audioFreq;								pMpegDecoder->SetMpegAudioParameters (&mpeginfo);								break;							}						}					}				}				p++;							}		}		if (StreamId == 0xbd)		{			if ((SubStreamId & 0x88) == 0x80)			{				// ac3				audioStreamId = StreamId;				audioSubStreamId = SubStreamId;				// assume 48000				audioFreq = 48000;				printf ("StreamId = %02x, SubStreamId = %02x, ac3\n", audioStreamId, audioSubStreamId);				AC3_PARAMETERS ac3info;				ac3info.rawOutput = 0;				ac3info.SamplesPerSecond = audioFreq;				pMpegDecoder->SetAC3Parameters (&ac3info);			}			if ((SubStreamId & 0x88) == 0x88)			{				// dts				audioStreamId = StreamId;				audioSubStreamId = SubStreamId;				// assume 48000				audioFreq = 48000;				printf ("StreamId = %02x, SubStreamId = %02x, ac3\n", audioStreamId, audioSubStreamId);				DTS_PARAMETERS dtsinfo;				dtsinfo.rawOutput = 1;				dtsinfo.SamplesPerSecond = audioFreq;				pMpegDecoder->SetDTSParameters (&dtsinfo);			}		}	}	if (videoStreamId == StreamId)	{		BufferPool *BP = &BPmpg;		int idx = ((int)pData - (int)BP->start_address) / BP->buffers_size;		ASSERT (idx >= 0);		addref_buffer (&(BP->B[idx]));		if (Flags & PTS_VALID_FLAG)		{			if (Flags & SCR_VALID_FLAG)			{				Scr = Scr * mpeg4TimeScale / 90000;				if (Scr == 0)					Scr = 1;			}			else if (videoFormat_mpeg12 == 0)			{				Scr = 0;			}			Flags = PTS_AVAILABLE_FLAG;			if (videoFormat_mpeg12 == 0)			{				Pts = Pts * mpeg4TimeScale / 90000;				Flags = CTS_AVAILABLE_FLAG;			}			DEBUGMSG (0, ("video: [%d] scr=%d, pts=%d\n", (int)Length, (int)Scr, (int)Pts));		}		else		{			DEBUGMSG (0, ("video: [%d]\n", (int)Length));			Flags = 0;		}		ASSERT (Length);		pMpegDecoder->WriteMpegVideo (pData, Length, &(BP->B[idx]), Flags, Scr, Pts);	}	if (iframe_only)		return 0;	if ((audioStreamId == StreamId) && (audioSubStreamId == SubStreamId))	{		BufferPool *BP = &BPmpg;		int idx = ((int)pData - (int)BP->start_address) / BP->buffers_size;		ASSERT (idx >= 0);

⌨️ 快捷键说明

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