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

📄 mp4.cpp

📁 EM8511s中使用的mp4播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				m_subpi_stco[si].advance32 (&error);				m_State = MP4_DEMUX_STATE_PARSE_CHUNK;				first_entry = m_subpi_stsc[si].get32 (&error);				if (first_entry == m_subpi_chunk_index[si])				{					m_subpi_stsc[si].advance32 (&error);					m_subpi_samples_per_chunk[si] = m_subpi_stsc[si].get32 (&error);					m_subpi_stsc[si].advance32 (&error);					m_subpi_stsc[si].get32 (&error);					m_subpi_stsc[si].advance32 (&error);									}				m_subpi_chunk_index[si]++;				m_currentID = 2 | (si << 8);				m_samples_per_chunk = m_subpi_samples_per_chunk[si];				ASSERT (m_samples_per_chunk);				DEBUGMSG (0, ("m_subpi_samples_per_chunk: %d\n", (RMint32)m_subpi_samples_per_chunk));				ASSERT (m_samples_per_chunk > 0);			}			else			{				// resync to next audio/video/subpi chunk				RMuint32 next_offset, aoffset, soffset;				ASSERT (voffset || aoffset0 || soffset0 || aoffset1 || soffset1);				if (soffset0 && soffset1)					soffset = MP4_MIN (soffset0, soffset1);				else					soffset = soffset0;				if (aoffset0 && aoffset1)					aoffset = MP4_MIN (aoffset0, aoffset1);				else					aoffset = aoffset0;				if (voffset && aoffset && soffset)				{					next_offset = MP4_MIN (soffset, aoffset);					next_offset = MP4_MIN (voffset, next_offset);				}				else if (voffset && aoffset)					next_offset = MP4_MIN (voffset, aoffset);				else if (voffset == 0)					next_offset = aoffset;				else					next_offset = voffset;				DEBUGMSG (1, ("*** resync to: %d\n", (RMint32)next_offset));				// need to seek?				if ((next_offset >= m_currentOffset) &&					(next_offset < (m_currentOffset + m_DataLeft)))				{					ASSERT ((RMint32)(next_offset - m_currentOffset) > 0);					ASSERT ((RMint32)(next_offset - m_currentOffset) < (RMint32)m_DataLeft);					m_pPutData += (RMint32)(next_offset - m_currentOffset);					m_DataLeft -= (RMint32)(next_offset - m_currentOffset);					ASSERT ((RMint32)m_DataLeft > 0);					m_currentOffset = next_offset;					m_DataLength = m_DataLeft;					ASSERT ((RMint32)m_DataLength > 0);				}				else				{					m_currentOffset = next_offset;					ASSERT (m_currentOffset);					m_CallbackTable.fseek (m_handle, next_offset, SEEK_SET, m_CallbackTable.context);					ASSERT (m_pData);					m_CallbackTable.release (m_pData, m_CallbackTable.context);					m_pData = 0;					m_State = MP4_DEMUX_STATE_GET_DATA;									}			}		}		break;	case MP4_DEMUX_STATE_PARSE_CHUNK:		if ((m_currentID & 0xff) == 0)		{						ASSERT (m_samples_per_chunk >= 0);			DEBUGMSG (0, ("(v) m_samples_per_chunk: %d\n", m_samples_per_chunk));			m_samples_per_chunk--;			if (m_samples_per_chunk < 0)			{				m_State = MP4_DEMUX_STATE_PARSE_DATA;				break;			}			m_total_chunk_size = 0;			m_chunkFlags = CHUNK_FLAGS_TIME_VALID;			if (m_video_sample_size == 0)			{				m_total_chunk_size = m_video_stsz.get32 (&error);				DEBUGMSG (0, (" video sample size: %d\n", (RMint32)m_total_chunk_size));				m_video_stsz.advance32 (&error);			}			else			{				m_total_chunk_size = m_video_sample_size;			}			m_firstVideoChunk = 0;			m_video_sample_count++;			if (m_video_stts_sample_delta_count == 0)			{				m_video_stts_sample_delta_count = m_video_stts.get32 (&error);				ASSERT (error == 0);				if (error == 0)				{					m_video_stts.advance32 (&error);					m_video_stts_sample_delta = m_video_stts.get32 (&error);					m_video_stts.advance32 (&error);				}			}			m_video_stts_sample_delta_count--;			if (m_video_ctts.IsInitialized ())			{				DEBUGMSG (0, ("m_video_ctts_sample_delta_count = %d\n", (int)m_video_ctts_sample_delta_count));				if (m_video_ctts_sample_delta_count == 0)				{					m_video_ctts_sample_delta_count = m_video_ctts.get32 (&error);					ASSERT (error == 0);					if (error == 0)					{						m_video_ctts.advance32 (&error);						m_video_ctts_sample_delta = m_video_ctts.get32 (&error);						DEBUGMSG (0, ("m_video_ctts_sample_delta = %d\n", (int)m_video_ctts_sample_delta));						m_video_ctts.advance32 (&error);					}				}				m_video_ctts_sample_delta_count--;								m_chunkTime = m_videoTime + m_video_ctts_sample_delta;				DEBUGMSG (0, ("m_chunkTime = %d (%d + %d)\n",					(int)m_chunkTime, (int)m_videoTime, (int)m_video_ctts_sample_delta));				m_videoTime += m_video_stts_sample_delta;			}				else			{				m_chunkTime = m_videoTime;				DEBUGMSG (0, ("m_chunkTime = %d (%d)\n", (int)m_chunkTime, (int)m_videoTime));				m_videoTime += m_video_stts_sample_delta;			}			m_chunkFlags |=	CHUNK_FLAGS_SAMPLE_START;			m_State = MP4_DEMUX_STATE_SEND_DATA;		}		else if ((m_currentID & 0xff) == 1)		{			RMint32 ai;			ai = m_current_au_index;			ASSERT (m_samples_per_chunk >= 0);			DEBUGMSG (0, ("(a) m_samples_per_chunk: %d\n", m_samples_per_chunk));			m_samples_per_chunk--;			if (m_samples_per_chunk < 0)			{				m_State = MP4_DEMUX_STATE_PARSE_DATA;				break;			}			m_total_chunk_size = 0;			m_chunkFlags = CHUNK_FLAGS_TIME_VALID;			if (m_audio_sample_size[ai] == 0)			{				m_total_chunk_size = m_audio_stsz[ai].get32 (&error);				ASSERT (m_total_chunk_size <= 4096);				ASSERT (m_total_chunk_size);				ASSERT (error == 0);				m_audio_stsz[ai].advance32 (&error);				ASSERT (error == 0);			}			else			{				m_total_chunk_size = m_audio_sample_size[ai];				ASSERT (m_total_chunk_size);			}			ASSERT (m_total_chunk_size <= 4096);			DEBUGMSG ((m_total_chunk_size > 4096), ("audio error: m_audio_sample_size = %d, m_total_chunk_size = %08lx\n",				m_audio_sample_size, m_total_chunk_size));			m_audio_sample_count[ai]++;			if (m_audio_stts_sample_delta_count[ai] == 0)			{				m_audio_stts_sample_delta_count[ai] = m_audio_stts[ai].get32 (&error);				ASSERT (error == 0);				if (error == 0)				{					m_audio_stts[ai].advance32 (&error);					m_audio_stts_sample_delta[ai] = m_audio_stts[ai].get32 (&error);					m_audio_stts[ai].advance32 (&error);				}									}			m_audio_stts_sample_delta_count[ai]--;			m_chunkTime = m_audioTime[ai];			m_audioTime[ai] += m_audio_stts_sample_delta[ai];			m_chunkFlags |=	CHUNK_FLAGS_SAMPLE_START;			m_State = MP4_DEMUX_STATE_SEND_DATA;		}		else if ((m_currentID & 0xff) == 2)		{			RMint32 si;			si = m_current_sp_index;			ASSERT (m_samples_per_chunk >= 0);			DEBUGMSG (0, ("(s) m_samples_per_chunk: %d\n", m_samples_per_chunk));			m_samples_per_chunk--;			if (m_samples_per_chunk < 0)			{				m_State = MP4_DEMUX_STATE_PARSE_DATA;				break;			}			m_total_chunk_size = 0;			m_chunkFlags = CHUNK_FLAGS_TIME_VALID;			if (m_subpi_sample_size[si] == 0)			{				m_total_chunk_size = m_subpi_stsz[si].get32 (&error);				ASSERT (m_total_chunk_size);				m_subpi_stsz[si].advance32 (&error);			}			else			{				m_total_chunk_size = m_subpi_sample_size[si];				ASSERT (m_total_chunk_size);			}			m_subpi_sample_count[si]++;			if (m_subpi_stts_sample_delta_count[si] == 0)			{				m_subpi_stts_sample_delta_count[si] = m_subpi_stts[si].get32 (&error);				ASSERT (error == 0);				if (error == 0)				{					m_subpi_stts[si].advance32 (&error);					m_subpi_stts_sample_delta[si] = m_subpi_stts[si].get32 (&error);					m_subpi_stts[si].advance32 (&error);				}									}			m_subpi_stts_sample_delta_count[si]--;			m_chunkTime = m_subpiTime[si];			m_subpiTime[si] += m_subpi_stts_sample_delta[si];			m_chunkFlags |=	CHUNK_FLAGS_SAMPLE_START;			m_State = MP4_DEMUX_STATE_SEND_DATA;		}		else			ASSERT (0);		break;	case MP4_DEMUX_STATE_SEND_DATA:				{			RMuint32 l;			// write m_total_chunk_size data			l = MP4_MIN (m_total_chunk_size, m_DataLeft);			if (l == m_total_chunk_size)				m_chunkFlags |= CHUNK_FLAGS_SAMPLE_END;			if (m_CallbackTable.putChunk (m_currentID, m_chunkFlags, m_chunkTime, m_pPutData, l, m_CallbackTable.context) != 0)			{				ASSERT (0);				break;			}			m_chunkFlags &= ~(CHUNK_FLAGS_TIME_VALID | CHUNK_FLAGS_SAMPLE_START | CHUNK_FLAGS_SAMPLE_END);			m_total_chunk_size -= l;			m_currentOffset += l;			ASSERT (m_currentOffset);			m_pPutData += l;			m_DataLeft -= l;			ASSERT ((RMint32)m_DataLeft >= 0);			if (m_DataLeft == 0)			{				ASSERT (m_pData);				m_CallbackTable.release (m_pData, m_CallbackTable.context);				m_pData = 0;				m_State = MP4_DEMUX_STATE_GET_DATA;				}			else			{				ASSERT (m_total_chunk_size == 0);				m_State = MP4_DEMUX_STATE_PARSE_CHUNK;			}		}		break;	case MP4_RANDOM_ACCESS_ONLY:		RandomAccessPointsOnly ();		break;	case MP4_DEMUX_STATE_END_OF_FILE:		return MP4_ERROR_END_OF_FILE;		break;	default:		break;	}	return MP4_ERROR_NO_ERROR;}#define PROCESS_CURRENT_RANDOM_ACCESS_POINT		0#define GET_RANDOM_ACCESS_DATA					1#define READ_CURRENT_RANDOM_ACCESS_POINT		2#define UPDATE_NEXT_RANDOM_ACCESS_POINT			3#define UPDATE_PREVIOUS_RANDOM_ACCESS_POINT		4RMuint32 MP4Demux::RandomAccessPointsOnly (){	RMuint32 error, sample_size, chunk_sample_count;	RMuint32 first_chunk, next_chunk, sample_description_index, chunk_offset, frame_no, chunk_index;	RMint32 sample_offset, i, frame_incr, rewind;	switch (m_RandomAccessState)	{	case PROCESS_CURRENT_RANDOM_ACCESS_POINT:		// before coming here, these variables should be initalized:		// m_currentRandomAccessPoint		// m_video_chunk_index		// m_video_samples_per_chunk		// m_samples_per_chunk		// m_video_sample_count		// find the chunk that this sample is in		chunk_index = m_video_chunk_index - 1;		chunk_index += (m_currentRandomAccessPoint - m_video_sample_count) / m_samples_per_chunk;		chunk_sample_count = m_video_sample_count + 			((m_currentRandomAccessPoint - m_video_sample_count)/m_samples_per_chunk)*m_samples_per_chunk;		m_video_stco.seek (chunk_index * 4);		chunk_offset = m_video_stco.get32 (&error);		ASSERT (error == 0);		// find the offset to this sample within this chunk		sample_offset = m_currentRandomAccessPoint - chunk_sample_count;		// calculate the file position of this random access point		if (m_video_sample_size)		{			chunk_offset += (m_video_sample_size * sample_offset);			sample_size = m_video_sample_size;		}		else		{			m_video_stsz.seek (chunk_sample_count * 4);			for (i=0; i<sample_offset; i++)			{				chunk_offset += m_video_stsz.get32 (&error);				m_video_stsz.advance32 (&error);				ASSERT (error == 0);			}			// calculate the size of this random access point			sample_size = m_video_stsz.get32 (&error);			ASSERT (error == 0);			m_video_stsz.seek (m_currentRandomAccessPoint * 4);			sample_size = m_video_stsz.get32 (&error);			ASSERT (error == 0);		}		seek (chunk_offset);		m_RandomAccessSampleSize = sample_size;		ASSERT (m_RandomAccessSampleSize);		m_RandomAccessState = GET_RANDOM_ACCESS_DATA;		m_chunkFlags = CHUNK_FLAGS_TIME_VALID | CHUNK_FLAGS_SAMPLE_START;		m_chunkTime = m_currentRandomAccessPoint * m_video_stts_sample_delta;#ifdef MP4_ENABLE_DEBUG		{			static int IFrameCounter = 0;			RMint32 h, m, s, t;			t = (RMint32)(m_chunkTime / m_tracktimescales[m_videoTrackIndex]);			h = (t / 3600);			m = (t - h * 3600) / 60;			s = t - h*3600 - m*60;			DEBUGMSG (1, ("(%d) send frame %d @%d %d bytes (%02d:%02d:%02d)\n",				IFrameCounter++,				(int)m_currentRandomAccessPoint, (int)chunk_offset, (int)sample_size,				h, m, s));		}		if (f == 0)			f = fopen ("d:\\iframe.m4v", "wb");		#endif		break;	case GET_RANDOM_ACCESS_DATA:		ASSERT (m_pRandomAccessData == 0);		if (m_CallbackTable.getData (&m_pRandomAccessData, &m_RandomLength, m_CallbackTable.context) == 0)		{			ASSERT (m_RandomLength);			m_CallbackTable.addref (m_pRandomAccessData, m_CallbackTable.context);			m_RandomAccessState = READ_CURRENT_RANDOM_ACCESS_POINT;		}				break;	case READ_CURRENT_RANDOM_ACCESS_POINT:		sample_size = MP4_MIN (m_RandomLength, m_RandomAccessSampleSize);		sample_size = m_CallbackTable.fread (m_handle, m_pRandomAccessData, sample_size, m_CallbackTable.context);#ifdef MP4_ENABLE_DEBUG				if (f)		{			fwrite (m_pRandomAccessData, 1, sample_size, f);		}		#endif		if (sample_size == 0)		{			ASSERT (0);			m_State = MP4_DEMUX_STATE_END_OF_FILE;			return MP4_ERROR_NO_ERROR;		}		ASSERT (m_pRandomAccessData);		DEBUGMSG (0, (" putChunk (%08lx, %08lx%08lx, %08lx, %d)\n",				(RMuint32)(m_chunkFlags),			(RMuint32)(m_chunkTime >> 32), (RMuint32)(m_chunkTime), 			(RMuint32)m_pRandomAccessData, (int)sample_size));		if (m_CallbackTable.putChunk (0, m_chunkFlags, m_chunkTime, m_pRandomAccessData, sample_size, m_CallbackTable.context) != 0)		{			ASSERT (0);			m_State = MP4_DEMUX_STATE_END_OF_FILE;			return MP4_ERROR_NO_ERROR;		}		m_CallbackTable.release (m_pRandomAccessData, m_CallbackTable.context);		m_chunkTime = 0;		m_chunkFlags = 0;		m_pRandomAccessData = 0;		m_RandomAccessSampleSize -= sample_size;		if (m_RandomAccessSampleSize == 0)		{			if (m_RandomAccessPointsOnly > 0)				m_RandomAccessState = UPDATE_NEXT_RANDOM_ACCESS_POINT;			else				m_RandomAccessState = UPDATE_PREVIOUS_RANDOM_ACCESS_POINT;		}		else			m_RandomAccessState = GET_RANDOM_ACCESS_DATA;		break;	case UPDATE_NEXT_RANDOM_ACCESS_POINT:		// re-initialize:		// m_currentRandomAccessPoint		// m_video_chunk_index		// m_video_samples_per_chunk		// m_samples_per_chunk		// m_video_sample_count		ASSERT (m_RandomAccessPointsOnly > 0);		m_currentRandomAccessPoint = m_video_stss.get32 (&error) - 1;				m_video_stss.advance32 (&error);

⌨️ 快捷键说明

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