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

📄 main.cpp

📁 EM8511s中使用的avi播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					RMuint8 *p = (RMuint8 *)get_buffer_address (&BPscan, idx);					memcpy (p, mp43scan_buffer, mp43scan_status);					while (mp43scan_status)					{						addref_buffer (&(BPscan.B[idx]));						buflen = MY_MIN (0xffff, mp43scan_status);						ASSERT (buflen);						mpegerr = pMpegDecoder->WriteMpegVideo (p, buflen, &(BPscan.B[idx]), 0, 0, 0);						ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);						if (mpegerr == MPEG_DECODER_ERROR_NO_ROOM)						{							release_buffer (&(BPscan.B[idx]));						}						mp43scan_status -= buflen;						p += buflen;					}				}				else					ASSERT (0);				mp43scan_status = 0;				aviFrameCounter++;				return 0;			}			// end filtering#endif			// send 0x000001b6 at the start of every picture			// for ms-mpeg4v3			if (flags & AVI_FLAG_CHUNK_START)			{				pic_startcode[0] = 0x00;				pic_startcode[1] = 0x00;				pic_startcode[2] = 0x01;				pic_startcode[3] = 0xb6;				videoTime = aviStartupDelay + ((RMint64)aviFrameCounter * (RMint64)aviTicksPerFrame);				DEBUGMSG (0, ("WriteMpegVideo (aviTime0 = %d, videoTime = %d)\n", (RMint32)aviTime0, (RMint32)videoTime));				mpegerr = pMpegDecoder->WriteMpegVideo (pic_startcode, 4, 0, CTS_AVAILABLE_FLAG, aviTime0, videoTime);				ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);				aviFrameCounter++;							}			flags = 0;		}		ASSERT (pMpegDecoder);		BufferPool *BP;		ASSERT (((int)buffer >= (int)avi_buffer) && ((int)buffer < ((int)avi_buffer + (AVI_BUFFERSIZE * AVI_NBUFFERS))));		BP = &BPavi;		int idx = ((int)buffer - (int)BP->start_address) / BP->buffers_size;		ASSERT (idx >= 0);		// break this chunk into < 64k blocks		RMuint8 *p = buffer;		RMuint32 tl = buflen;		RMuint32 flag = 0;		if (flags & AVI_FLAG_CHUNK_START)		{						if (buflen > 4)			{				// if I or P frame				if (((buffer[4] & 0xc0) == 0x40) || 					((buffer[4] & 0xc0) == 0x00))				{					flag = CTS_AVAILABLE_FLAG;					videoTime = aviStartupDelay + ((RMint64)aviFrameCounter * (RMint64)aviTicksPerFrame);				}			}			aviFrameCounter++;			DEBUGMSG (0, ("(2) aviFrameCounter: %lu\n", aviFrameCounter));		}		while (tl)		{			addref_buffer (&(BP->B[idx]));			buflen = MY_MIN (0xffff, tl);			DEBUGMSG (0, ("WriteMpegVideo (%d, %d, %d)\n", (RMint32)videoTime, (RMint32)buflen, aviFrameCounter));			DEBUGMSG (0, ("%02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]));			ASSERT (buflen);			if (KeyFramesOnly)				flag = 0;			DEBUGMSG (0, ("WriteMpegVideo (KeyFramesOnly = %d, flag = %d, aviTime0 = %d, videoTime = %d)\n", 				(RMint32)KeyFramesOnly, (RMint32)flag, (RMint32)aviTime0, (RMint32)videoTime));			if (flag)				mpegerr = pMpegDecoder->WriteMpegVideo (p, buflen, &(BP->B[idx]), flag, aviTime0, videoTime);			else				mpegerr = pMpegDecoder->WriteMpegVideo (p, buflen, &(BP->B[idx]), 0, 0, 0);			ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);			if (mpegerr == MPEG_DECODER_ERROR_NO_ROOM)			{				release_buffer (&(BP->B[idx]));			}			tl -= buflen;			p += buflen;			flag = 0;		}	}	else if ((chunkid[2] == 'w') && (chunkid[3] == 'b'))	{		// audio chunk		if ((chunkid[0] == selected_audio_stream[0]) &&			(chunkid[1] == selected_audio_stream[1]))		{			DEBUGMSG (0, ("audio chunk (%c%c%c%c, 0x%08lx, %lu, 0x%08lx)\n", 				chunkid[0], chunkid[1], chunkid[2], chunkid[3],				buffer, buflen, flags));			if (selected_audio_stream_format == 0x55)			{				// mp3				if (pMP3BufferDecoder)				{					if (pMP3BufferDecoder->DecodeBuffer (buffer, buflen) == MP3_DECODER_ERROR_BAD_MP3_BUFFER)						tbytes += (1152 * 2 * NumberOfChannels);				}			}			else if (selected_audio_stream_format == 0x2000)			{					// ac3				BufferPool *BP;				ASSERT (((int)buffer >= (int)avi_buffer) && ((int)buffer < ((int)avi_buffer + (AVI_BUFFERSIZE * AVI_NBUFFERS))));				BP = &BPavi;				int idx = ((int)buffer - (int)BP->start_address) / BP->buffers_size;				ASSERT (idx >= 0);				// break this chunk into < 64k blocks				RMuint8 *p = buffer;				RMuint32 tl = buflen;				RMuint32 flag = 0;				avi_initial_start = 0;				// find the ac3FrameSize				if ((buflen > 4) && (ac3FrameSize == 0))				{					RMint32 ac3l = buflen;					RMuint8 *pac3 = buffer;					while (ac3l > 4)					{						if ((pac3[0] == 0x0b) && (pac3[1] == 0x77))						{							int fscod = (pac3[4] >> 6) & 0x3;							int frmsizecod = pac3[4] & 0x3f;							if ((fscod < 3) && (frmsizecod <= 0x25))							{								ac3FrameSize = frmsizecod_table[fscod][frmsizecod] * 2;								DEBUGMSG (1, ("ac3FrameSize: %d\n", ac3FrameSize));								break;							}						}						pac3++;						ac3l--;					}				}				if (ac3FrameSize)				{					RMint64 nac3frames = (RMint64)tbytes / ac3FrameSize;					if (tbytes % ac3FrameSize)						nac3frames++;					flag = CTS_AVAILABLE_FLAG;					audioTime = aviStartupDelay + 						((RMint64)nac3frames * 256 * 6 * (RMint64)aviTimeScale / (RMint64)SamplesPerSecond);				}				// fill out the firstaccessunitpointer field				// to make ac3 sync better				int firstaccessunitpointer = 0;				if (flag && ac3FrameSize)					firstaccessunitpointer = ac3FrameSize - (tbytes % ac3FrameSize);				tbytes += buflen;				while (tl)				{					addref_buffer (&(BP->B[idx]));					buflen = MY_MIN (0x2000, tl);					ASSERT (pMpegDecoder);					DEBUGMSG (0, ("WriteAC3 (%d)\n", (RMint32)audioTime));					mpegerr = pMpegDecoder->WriteAC3 (p, buflen, &(BP->B[idx]), flag, aviTime0, audioTime, firstaccessunitpointer);					ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);					tl -= buflen;					p += buflen;					flag = 0;				}							}			else if (selected_audio_stream_format == 0x2001)			{					// dts				BufferPool *BP;				ASSERT (((int)buffer >= (int)avi_buffer) && ((int)buffer < ((int)avi_buffer + (AVI_BUFFERSIZE * AVI_NBUFFERS))));				BP = &BPavi;				int idx = ((int)buffer - (int)BP->start_address) / BP->buffers_size;				ASSERT (idx >= 0);				// break this chunk into < 4k blocks				RMuint8 *p = buffer;				RMuint32 tl = buflen;				RMuint32 flag = 0;				// find the dts frame size				if ((buflen > 4) && ((dtsFrameSize == 0) || (avi_initial_start)))				{					RMint32 dtsl = buflen;					RMuint8 *pdts = buffer;					while (dtsl > 4)					{						if ((pdts[0] == 0x7f) && 							(pdts[1] == 0xfe) &&							(pdts[2] == 0x80) &&							(pdts[3] == 0x01))						{							dtsFrameSize = (								((RMuint32)(pdts[5] & 0x03) << 12) | 								((RMuint32)(pdts[6]       ) <<  4) |								((RMuint32)(pdts[7] & 0xf0) >>  4));							dtsFrameSize++;														DEBUGMSG (1, ("dtsFrameSize = %d\n", (RMint32)dtsFrameSize));							p = pdts;							buflen = dtsl;							tl = buflen;							break;						}						pdts++;						dtsl--;					}				}				if (dtsFrameSize == 0)					return 0;												if ((tbytes == 0) || (avi_initial_start))				{					avi_initial_start = 0;					RMint64 ndtsframes = (RMint64)tbytes / dtsFrameSize;					if (tbytes && (tbytes % dtsFrameSize))						ndtsframes++;					flag = CTS_AVAILABLE_FLAG;					audioTime = aviStartupDelay + 						((RMint64)ndtsframes * 512 * (RMint64)aviTimeScale / (RMint64)SamplesPerSecond);				}								tbytes += buflen;				while (tl)				{					addref_buffer (&(BP->B[idx]));					buflen = MY_MIN (0x1000, tl);					ASSERT (pMpegDecoder);					DEBUGMSG (0, ("WriteDTS (%d, %d)\n", (RMint32)buflen, (RMint32)audioTime));					DEBUGMSG (flag, ("WriteDTS (%02x %02x %02x %02x, %d)\n", p[0], p[1], p[2], p[3], (RMint32)audioTime));					mpegerr = pMpegDecoder->WriteDTS (p, buflen, &(BP->B[idx]), flag, aviTime0, audioTime, buflen/dtsFrameSize, 0);					ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);					tl -= buflen;					p += buflen;					flag = 0;				}							}			else if (selected_audio_stream_format == 0x1)			{					// pcm				BufferPool *BP;				ASSERT (((int)buffer >= (int)avi_buffer) && ((int)buffer < ((int)avi_buffer + (AVI_BUFFERSIZE * AVI_NBUFFERS))));				BP = &BPavi;				int idx = ((int)buffer - (int)BP->start_address) / BP->buffers_size;				ASSERT (idx >= 0);				// swap bytes				RMuint8 *p = buffer;				RMuint32 tl = buflen;				RMuint32 flag = CTS_AVAILABLE_FLAG;				audioTime = aviStartupDelay + ((RMint64)tbytes * (RMint64)aviTimeScale / (RMint64)BytesPerSecond);				RMuint8 tmp;				for (RMuint32 i=0; i<buflen; i+=2)				{					tmp = p[0];					p[0] = p[1];					p[1] = tmp;					p += 2;				}				p = buffer;				tbytes += buflen;				// break this chunk into < 8k blocks				while (tl)				{					addref_buffer (&(BP->B[idx]));					buflen = MY_MIN (0x2000, tl);					ASSERT (pMpegDecoder);					DEBUGMSG (0, ("WritePCM (%d)\n", (RMint32)audioTime));					mpegerr = pMpegDecoder->WritePCM (p, buflen, &(BP->B[idx]), flag, aviTime0, audioTime);					ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);					if (mpegerr == MPEG_DECODER_ERROR_NO_ROOM)					{						release_buffer (&(BP->B[idx]));					}					tl -= buflen;					p += buflen;					flag = 0;				}							}		}		else		{			// ok - multiple audio streams		}	}	else if ((chunkid[2] == 'd') && (chunkid[3] == 'd'))	{		// divx drm chunk		ASSERT (0);	}	else	{		// unknown chunk	}	return 0;}// ***********************************************// end callback functions requied by the avi demux// ***********************************************// perform a seek in an avi fileint avi_seek (int t){	MPEG_DECODER_ERROR mpegerr;	RMuint32 vp, ap, ab;	if ((selected_audio_stream_format == 0x2001) && (dtsFrameSize == 0))		return -1;	// ask the demux to perform a seek	if (pAVIDemux->Seek (t, 1, &vp, &ap, &ab) == AVI_DEMUX_ERROR_NO_ERROR)	{		if (pAVISubtitle)			pAVISubtitle->Seek (t);		// flush mpeg decoder		pMpegDecoder->Stop ();				deinit_buffer_pool (&BPavi);		deinit_buffer_pool (&BPpcm);		deinit_buffer_pool (&BPscan);		init_buffer_pool (&BPscan, mp43pending_buffer, 1024*128, N_MP43_SCAN_BUFFER);		init_buffer_pool (&BPavi, avi_buffer, AVI_BUFFERSIZE, AVI_NBUFFERS);		init_buffer_pool (&BPpcm, pcm_buffer, PCM_BUFFERSIZE, PCM_NBUFFERS);		pMpegDecoder->Play ();		// calculate the initial audio and video time		aviFrameCounter = vp; 		videoTime = aviStartupDelay + ((RMint64)aviFrameCounter * (RMint64)aviTicksPerFrame);		if (ab)		{			if (selected_audio_stream_format == 0x55)			{				DEBUGMSG (1, ("calculating the audioTime based on constant bitrate mp3\n"));				audioTime = aviStartupDelay + ((RMint64)ap * (RMint64)aviTimeScale / (RMint64)CompressedBytesPerSecond);				tbytes = (RMuint32)((RMint64)ap * (RMint64)BytesPerSecond / (RMint64)CompressedBytesPerSecond);			}			else			{				DEBUGMSG (1, ("calculating the audioTime based on constant bitrate\n"));				avi_initial_start = 1;				tbytes = ap;				audioTime = aviStartupDelay + ((RMint64)tbytes * (RMint64)aviTimeScale / (RMint64)CompressedBytesPerSecond);			}		}		else		{			// must be MP3			ASSERT (selected_audio_stream_format == 0x55);			DEBUGMSG (1, ("calculating the audioTime based on variable bitrate mp3\n"));			audioTime = aviStartupDelay + ((RMint64)ap * (RMint64)1152 * (RMint64)aviTimeScale / (RMint64)SamplesPerSecond);			tbytes = (RMint64)ap * (RMint64)1152 * (NumberOfBitsPerSample / 8) * NumberOfChannels;		}		DEBUGMSG (1, ("aviFrameCounter = %lu\n", aviFrameCounter));		DEBUGMSG (1, ("tbytes = %lu (%d * %d / %d)\n", tbytes, ap, BytesPerSecond, CompressedBytesPerSecond));		aviTime0 = MY_MIN (audioTime, videoTime);		if (aviTime0 == 0)			aviTime0 = 1;		RMint8 text[64];		RMint64 t, hours, minutes, seconds;		t = videoTime / aviTimeScale;		hours = t / 3600;		minutes = (t - hours * 3600) / 60;		seconds = t - hours*3600 - minutes*60;		DEBUGMSG (1, ("videoTime = %lu (%02d:%02d:%02d)\n", (RMuint32)videoTime, 			(RMint32)hours, (RMint32)minutes, (RMint32)seconds));		t = audioTime / aviTimeScale;		hours = t / 3600;		minutes = (t - hours * 3600) / 60;		seconds = t - hours*3600 - minutes*60;		DEBUGMSG (1, ("audioTime = %lu (%02d:%02d:%02d)\n", (RMuint32)audioTime,			(RMint32)hours, (RMint32)minutes, (RMint32)seconds));		DEBUGMSG (1, ("aviTime0  = %lu\n", (RMuint32)aviTime0));		// send an initial VOL header		RMuint32 length, i;		RMint32 idx = find_free_buffer (&BPavi, 0);		ASSERT (idx >= 0);		RMuint8 *p = (RMuint8 *)get_buffer_address (&BPavi, idx);		length = BPavi.buffers_size;		if (msmpeg4v3)		{			MP43_filter_flush (&MP43Scanner);			DEBUGMSG (1, ("create a vol header (seek)\n"));			VOLHdrLength = MP43_DSI_Generator (VOLHdr, currentScale, currentRate, currentWidth, currentHeight);			addref_buffer (&BPavi.B[idx]);			memcpy (p, VOLHdr, VOLHdrLength);			mpegerr = pMpegDecoder->WriteMpegVideo (p, VOLHdrLength, &BPavi.B[idx], 0, 0, 0);			ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);			if (mpegerr == MPEG_DECODER_ERROR_NO_ROOM)			{				release_buffer (&BPavi.B[idx]);			}			mp43scan_status = 0;		}		else		{			// there should always be a vol header at frame 0			pAVIDemux->GetFrame (0, p, &length);			p += 8;			RMuint8 *pVOLHdr = p;			// find the vol header			for (i=0; i<length-4; i++)			{				if ((p[0] == 0x00) && 					(p[1] == 0x00) &&					(p[2] == 0x01) &&					(p[3] == 0xb6))				{					ASSERT (pMpegDecoder);					ASSERT (i);					if (i)					{						MPEG_DECODER_ERROR mpegerr;						DEBUGMSG (1, ("sending volheader: %d bytes\n", i));						addref_buffer (&BPavi.B[idx]);						ASSERT (i);						mpegerr = pMpegDecoder->WriteMpegVideo (pVOLHdr, i, &BPavi.B[idx], 0, 0, 0);						ASSERT (mpegerr == MPEG_DECODER_ERROR_NO_ERROR);						if (mpegerr == MPEG_DECODER_ERROR_NO_ROOM)						{							release_buffer (&BPavi.B[idx]);						}					}					break;				}				p++;								}				}	}			else	{		DEBUGMSG (1, ("pAVIDemux->Seek (%d) failed.\n", t));		return -1;	}	return 0;}// send key frames onlyint avi_keyframesonly (int direction){	MPEG_DECODER_ERROR mpegerr;	RMuint32 vp;	// set the delay between key frames	// a longer delay will forward/reverse seem slower	// a shorter delay will make forward/reverse seem faster	// note that the quickest the frames will advance also	// depends on the seeking speed of your dvdrom drive	pAVIDemux->SetKeyFrameDelay (250);	DEBUGMSG (1, ("avi_keyframesonly ...\n"));	AVI_DEMUX_ERROR errorcode;	errorcode = pAVIDemux->KeyFramesOnly ((RMint32)direction);

⌨️ 快捷键说明

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