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

📄 avi.cpp

📁 EM8511s中使用的avi播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					m_chunkstart = 0;					m_bytecounter += buflen;					p += buflen;					buflen = 0;				}				else				{					// not tested					ASSERT (0);					m_savedbuf = buf;					m_savedbuflen = buflen;									m_savedp = p;					m_savedstate = AVI_DEMUX_STATE_WRITE_CHUNK;					m_demuxstate = AVI_DEMUX_STATE_RESTORE_STATE;					return AVI_DEMUX_ERROR_NO_ERROR;				}			}			break;		}					}	ASSERT (m_CallbackTable.release);	m_CallbackTable.release (buf, m_CallbackTable.context);	return AVI_DEMUX_ERROR_NO_ERROR;}#define AVI_DEMUX_KEYFRAMEONLY_STATE_NEXT_KEYFRAME	0#define AVI_DEMUX_KEYFRAMEONLY_STATE_PREV_KEYFRAME	1#define AVI_DEMUX_KEYFRAMEONLY_STATE_SEND_KEYFRAME	2#define AVI_DEMUX_KEYFRAMEONLY_STATE_DELAY			3#include <stdio.h>AVI_DEMUX_ERROR	AVIDemux::ScheduleKeyFramesOnly (){	ASSERT (m_moviOffset);	RMuint8 *p;	RMuint32 buflen, n;	RMint32 i;	RMuint32 err;	switch (m_KeyFrameOnlyState)	{	case AVI_DEMUX_KEYFRAMEONLY_STATE_NEXT_KEYFRAME:		// get the next key frame		for (i=m_CurrentIndex; i<m_IndexCacheValid; i++)		{			if (((m_IndexCache[i].ckid & 0xffff0000) == 0x62640000) ||				((m_IndexCache[i].ckid & 0xffff0000) == 0x63640000))			{				m_currentFramePosition++;				if (m_IndexCache[i].dwFlags & AVI_FLAGS_KEYFRAME)				{					m_CurrentIndex = i + 1;					if (m_IndexIsRelativeToStartOfFile)						m_KeyFrameOffset = m_IndexCache[i].dwChunkOffset + 4;					else						m_KeyFrameOffset = m_moviOffset + m_IndexCache[i].dwChunkOffset + 4;					m_KeyFrameLength = m_IndexCache[i].dwChunkLength;					ASSERT ((RMint32)m_KeyFrameLength > 0);					m_KeyFrameOnlyState = AVI_DEMUX_KEYFRAMEONLY_STATE_DELAY;					m_chunkid[0] = '0';					m_chunkid[1] = '0';					m_chunkid[2] = 'd';					m_chunkid[3] = 'c';					m_KeyFrameFlags = AVI_FLAG_CHUNK_START;					m_CallbackTable.info (AVI_DEMUX_KEYFRAME_POSITION, (void *)(m_currentFramePosition - 1), m_CallbackTable.context);					m_CallbackTable.fseek (m_handle, m_KeyFrameOffset, m_CallbackTable.context);					break;				}			}		}		if (i == m_IndexCacheValid)		{			// reload index and try again			m_IndexCacheOffset += (m_IndexCacheValid * sizeof (AVI_INDEXENTRY));			m_CallbackTable.fseek (m_handle, m_IndexCacheOffset, m_CallbackTable.context);			n = m_CallbackTable.fread (m_handle, &m_IndexCache, sizeof (AVI_INDEXENTRY) * AVI_INDEX_CACHE_SIZE, m_CallbackTable.context);			m_IndexCacheValid = n / sizeof (AVI_INDEXENTRY);			m_CurrentIndex = 0;			if ((m_IndexCacheValid == 0) || (m_IndexCacheOffset > (m_idx1Offset + m_idx1Length)))				return AVI_DEMUX_ERROR_FILE_DONE;		}		break;	case AVI_DEMUX_KEYFRAMEONLY_STATE_PREV_KEYFRAME:		// get the previous key frame		for (i=m_CurrentIndex; i>=0; i--)		{			if (((m_IndexCache[i].ckid & 0xffff0000) == 0x62640000) ||				((m_IndexCache[i].ckid & 0xffff0000) == 0x63640000))			{				m_currentFramePosition--;				if (m_IndexCache[i].dwFlags & AVI_FLAGS_KEYFRAME)				{					m_CurrentIndex = i - 1;					if (m_IndexIsRelativeToStartOfFile)						m_KeyFrameOffset = m_IndexCache[i].dwChunkOffset + 4;					else						m_KeyFrameOffset = m_moviOffset + m_IndexCache[i].dwChunkOffset + 4;					m_KeyFrameLength = m_IndexCache[i].dwChunkLength;					ASSERT ((RMint32)m_KeyFrameLength > 0);					m_KeyFrameOnlyState = AVI_DEMUX_KEYFRAMEONLY_STATE_DELAY;					m_chunkid[0] = '0';					m_chunkid[1] = '0';					m_chunkid[2] = 'd';					m_chunkid[3] = 'c';					m_KeyFrameFlags = AVI_FLAG_CHUNK_START;					m_CallbackTable.info (AVI_DEMUX_KEYFRAME_POSITION, (void *)(m_currentFramePosition + 1), m_CallbackTable.context);					m_CallbackTable.fseek (m_handle, m_KeyFrameOffset, m_CallbackTable.context);					break;				}			}		}		if (i < 0)		{			// reload index cache and try again			if (m_IndexCacheOffset == m_idx1Offset)				return AVI_DEMUX_ERROR_FILE_DONE;			m_IndexCacheOffset -= (sizeof (AVI_INDEXENTRY) * AVI_INDEX_CACHE_SIZE);			if (m_IndexCacheOffset < m_idx1Offset)			{				m_CurrentIndex = AVI_INDEX_CACHE_SIZE - ((m_idx1Offset - m_IndexCacheOffset) / sizeof (AVI_INDEXENTRY)) - 1;				ASSERT ((RMint32)m_CurrentIndex > 0);				m_IndexCacheOffset = m_idx1Offset;				ASSERT ((RMint32)m_IndexCacheOffset > 0);			}			else			{				ASSERT ((RMint32)m_IndexCacheOffset > 0);				m_CurrentIndex = AVI_INDEX_CACHE_SIZE - 1;				ASSERT ((RMint32)m_CurrentIndex > 0);			}			m_CallbackTable.fseek (m_handle, m_IndexCacheOffset, m_CallbackTable.context);			n = m_CallbackTable.fread (m_handle, &m_IndexCache, sizeof (AVI_INDEXENTRY) * AVI_INDEX_CACHE_SIZE, m_CallbackTable.context);			m_IndexCacheValid = n / sizeof (AVI_INDEXENTRY);		}		break;	case AVI_DEMUX_KEYFRAMEONLY_STATE_SEND_KEYFRAME:		if (m_CallbackTable.getbuffer (&p, &buflen, m_CallbackTable.context))			return AVI_DEMUX_ERROR_NO_BUFFER_AVAILABLE;		n = AVI_MIN (buflen, m_KeyFrameLength); 		n = m_CallbackTable.fread (m_handle, p, n, m_CallbackTable.context);		m_KeyFrameLength -= n;		if (m_KeyFrameLength == 0)		{			DEBUGMSG (1, ("AVI_DEMUX_KEYFRAMEONLY_STATE_SEND_KEYFRAME: %d\n", (RMint32)m_currentFramePosition));			m_KeyFrameFlags |= AVI_FLAG_CHUNK_END;			if (m_KeyFramesOnly > 0)				m_KeyFrameOnlyState = AVI_DEMUX_KEYFRAMEONLY_STATE_NEXT_KEYFRAME;			else				m_KeyFrameOnlyState = AVI_DEMUX_KEYFRAMEONLY_STATE_PREV_KEYFRAME;			ASSERT (m_CallbackTable.gettimems);			m_KeyFrameDelay_t0 = m_CallbackTable.gettimems (m_CallbackTable.context);		}				err = m_CallbackTable.putChunk (m_chunkid, p, n, m_KeyFrameFlags, m_CallbackTable.context);		// not allowed to pend only key frames		ASSERT (err == 0);		m_KeyFrameFlags = 0;		break;	case AVI_DEMUX_KEYFRAMEONLY_STATE_DELAY:				i = m_CallbackTable.gettimems (m_CallbackTable.context);		if ((RMint32)(i - m_KeyFrameDelay_t0) > m_KeyFrameDelayInMS)		{			m_KeyFrameOnlyState = AVI_DEMUX_KEYFRAMEONLY_STATE_SEND_KEYFRAME;		}		break;	}	return AVI_DEMUX_ERROR_NO_ERROR;}AVI_DEMUX_ERROR AVIDemux::Seek (RMuint32 seconds, RMuint32 audiostreamno, RMuint32 *pvideoposition, RMuint32 *paudioposition, RMuint32 *paudiobyte){	RMuint32 i;	RMuint32 s0, s1, Rate=24000, Scale=1000;	if (m_idx1Offset == 0)	{		ASSERT (0);		return AVI_DEMUX_ERROR_INVALID_PARAMETER;	}	ASSERT (audiostreamno <	AVI_MAX_STREAMS_SUPPORTED);	if (audiostreamno >= AVI_MAX_STREAMS_SUPPORTED)		return AVI_DEMUX_ERROR_INVALID_PARAMETER;	DEBUGMSG (1, ("AVI Seek (%d)\n", (RMint32)seconds));	for (i=0; i<AVI_MAX_STREAMS_SUPPORTED; i++)	{				if (AVI_PACKED_STRUCTURE_ACCESS (m_StreamHeaders[i], fccType) == AVI_FOURCC ('v','i','d','s'))		{			Rate = AVI_PACKED_STRUCTURE_ACCESS (m_StreamHeaders[i], Rate);			Scale = AVI_PACKED_STRUCTURE_ACCESS (m_StreamHeaders[i], Scale);			DEBUGMSG (1, (" Rate: %lu\n", AVI_PACKED_STRUCTURE_ACCESS (m_StreamHeaders[i], Rate)));			DEBUGMSG (1, (" Scale: %lu\n", AVI_PACKED_STRUCTURE_ACCESS (m_StreamHeaders[i], Scale)));			break;		}	}	for (i=0; i<m_nIndexHelper-1; i++)	{		s0 = m_IndexHelper[i].videoFrameCount * Scale / Rate;		s1 = m_IndexHelper[i+1].videoFrameCount * Scale / Rate;		if ((seconds >= s0) && (seconds <s1))		{						DEBUGMSG (1, (" videoFrameCount: %lu\n", m_IndexHelper[i].videoFrameCount));			DEBUGMSG (1, (" audioByteOrFrameCount: %lu\n", m_IndexHelper[i].audioByteOrFrameCount[audiostreamno]));			DEBUGMSG (1, (" vbrmp3: %lu\n", m_vbrmp3[audiostreamno]));			RMuint32 offset;			if (m_IndexIsRelativeToStartOfFile)				offset = m_IndexHelper[i].chunkOffset;			else				offset = m_moviOffset + m_IndexHelper[i].chunkOffset - 4;			DEBUGMSG (1, (" seek to fileposition %lu.\n", offset));			m_CallbackTable.fseek (m_handle, offset, m_CallbackTable.context);			m_demuxstate = AVI_DEMUX_STATE_CHUNK_NAME_BYTE0;			*pvideoposition = m_IndexHelper[i].videoFrameCount;			*paudioposition = m_IndexHelper[i].audioByteOrFrameCount[audiostreamno];			if (m_vbrmp3[audiostreamno])				*paudiobyte = 0;			else				*paudiobyte = 1;			m_currentFramePosition = m_IndexHelper[i].videoFrameCount;			DEBUGMSG (1, (" seek ok.\n"));			return AVI_DEMUX_ERROR_NO_ERROR;		}	}	DEBUGMSG (1, (" seek failed.\n"));	return AVI_DEMUX_ERROR_INVALID_PARAMETER;}AVI_DEMUX_ERROR AVIDemux::KeyFramesOnly (RMint32 direction){	RMuint32 i, n;	RMuint32 p0, p1;	DEBUGMSG (1, ("AVIDemux::KeyFramesOnly (%d)\n", direction));	if (m_idx1Offset == 0)	{		ASSERT (0);		return AVI_DEMUX_ERROR_INVALID_PARAMETER;	}	if (direction == 0)	{		m_KeyFramesOnly = 0;		// continue normal demux from the current position		m_CallbackTable.fseek (m_handle, m_KeyFrameOffset - 4, m_CallbackTable.context);		return AVI_DEMUX_ERROR_NO_ERROR;	}	m_KeyFrameDelay_t0 = m_CallbackTable.gettimems (m_CallbackTable.context);	RMuint32 currentpos = m_CallbackTable.ftell (m_handle, m_CallbackTable.context);	m_KeyFrameOffset = currentpos + 4;	DEBUGMSG (1, ("m_KeyFrameOffset = %d (%d + 4)\n", 		(RMint32)m_KeyFrameOffset, (RMint32)currentpos));	DEBUGMSG (1, ("m_nIndexHelper = %d\n", (RMint32)m_nIndexHelper));	DEBUGMSG (1, ("m_currentFramePosition = %d\n", (RMint32)m_currentFramePosition));	// find the nearest key frame	for (i=0; i<m_nIndexHelper-1; i++)	{		if (m_IndexHelper[i].videoFrameCount)			p0 = m_IndexHelper[i].videoFrameCount - 1;		else			p0 = 0;		if (m_IndexHelper[i+1].videoFrameCount)			p1 = m_IndexHelper[i+1].videoFrameCount - 1;		else			p1 = 0;		DEBUGMSG (1, ("p0 = %d, p1 = %d\n", (RMint32)p0, (RMint32)p1));		if ((m_currentFramePosition >= p0) && (m_currentFramePosition < p1))		{			// initialize the index cache			m_KeyFramesOnly = direction;			if (direction > 0)			{				m_IndexCacheOffset = m_idx1Offset + (m_IndexHelper[i].indexOffset * sizeof (AVI_INDEXENTRY));				m_CallbackTable.fseek (m_handle, m_IndexCacheOffset, m_CallbackTable.context);				n = m_CallbackTable.fread (m_handle, &m_IndexCache, sizeof (AVI_INDEXENTRY) * AVI_INDEX_CACHE_SIZE, m_CallbackTable.context);				m_IndexCacheValid = n / sizeof (AVI_INDEXENTRY);				m_KeyFrameOnlyState = AVI_DEMUX_KEYFRAMEONLY_STATE_NEXT_KEYFRAME;				m_CurrentIndex = 0;			}			else			{				if (m_IndexHelper[i].indexOffset < AVI_INDEX_CACHE_SIZE)				{					m_IndexCacheOffset = m_idx1Offset;					ASSERT ((RMint32)m_IndexCacheOffset >= 0);					m_CurrentIndex = m_IndexHelper[i].indexOffset;					ASSERT ((RMint32)m_CurrentIndex >= 0);				}				else				{					m_IndexCacheOffset = m_idx1Offset + (m_IndexHelper[i].indexOffset - AVI_INDEX_CACHE_SIZE) * sizeof (AVI_INDEXENTRY);					ASSERT ((RMint32)m_IndexCacheOffset >= 0);					m_CurrentIndex = AVI_INDEX_CACHE_SIZE - 1;					ASSERT ((RMint32)m_CurrentIndex >= 0);				}				m_CallbackTable.fseek (m_handle, m_IndexCacheOffset, m_CallbackTable.context);				n = m_CallbackTable.fread (m_handle, &m_IndexCache, sizeof (AVI_INDEXENTRY) * AVI_INDEX_CACHE_SIZE, m_CallbackTable.context);				m_IndexCacheValid = n / sizeof (AVI_INDEXENTRY);				m_KeyFrameOnlyState = AVI_DEMUX_KEYFRAMEONLY_STATE_PREV_KEYFRAME;			}						m_CallbackTable.fseek (m_handle, currentpos, m_CallbackTable.context);			return AVI_DEMUX_ERROR_NO_ERROR;		}	}	m_CallbackTable.fseek (m_handle, currentpos, m_CallbackTable.context);	return AVI_DEMUX_ERROR_NO_KEYFRAME;}AVI_DEMUX_ERROR AVIDemux::GetFrame (RMuint32 frameno, RMuint8 *buffer, RMuint32 *length){	if (frameno)	{		ASSERT (0);		return AVI_DEMUX_ERROR_NOT_IMPLEMENTED;	}	if (m_idx1Offset == 0)	{		ASSERT (0);		return AVI_DEMUX_ERROR_INVALID_PARAMETER;	}	RMuint32 currentpos = m_CallbackTable.ftell (m_handle, m_CallbackTable.context);	AVI_INDEXENTRY idx;	m_CallbackTable.fseek (m_handle, m_idx1Offset, m_CallbackTable.context);	while (1)	{		if (m_CallbackTable.fread (m_handle, &idx, sizeof(idx), m_CallbackTable.context) != sizeof(idx))		{			ASSERT (0);			m_CallbackTable.fseek (m_handle, currentpos, m_CallbackTable.context);			return AVI_DEMUX_ERROR_INVALID_PARAMETER;		}		if (((idx.ckid & 0xffff0000) == 0x62640000) ||			((idx.ckid & 0xffff0000) == 0x63640000))		{			ASSERT (idx.dwFlags & AVI_FLAGS_KEYFRAME);			if (m_IndexIsRelativeToStartOfFile)				m_CallbackTable.fseek (m_handle, idx.dwChunkOffset, m_CallbackTable.context);			else			{				ASSERT ((RMint32)(m_moviOffset + idx.dwChunkOffset - 4) > 0);				m_CallbackTable.fseek (m_handle, m_moviOffset + idx.dwChunkOffset - 4, m_CallbackTable.context);			}			*length = AVI_MIN (*length, idx.dwChunkLength);			*length = m_CallbackTable.fread (m_handle, buffer, *length, m_CallbackTable.context);			break;		}	}	m_CallbackTable.fseek (m_handle, currentpos, m_CallbackTable.context);	return AVI_DEMUX_ERROR_NO_ERROR;}AVI_DEMUX_ERROR AVIDemux::SetKeyFrameDelay (RMuint32 delay_ms){	m_KeyFrameDelayInMS = delay_ms;	return AVI_DEMUX_ERROR_NO_ERROR;}AVI_DEMUX_ERROR AVIDemux::IsStreamNumberVBR (RMuint32 audiostreamno, RMuint32 *is_vbr){	*is_vbr = m_vbrmp3[audiostreamno];	return AVI_DEMUX_ERROR_NO_ERROR;}

⌨️ 快捷键说明

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