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

📄 mp4.cpp

📁 EM8511s中使用的mp4播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	return MP4_ERROR_NO_ERROR;}MP4_ERROR MP4Demux::Next (RMint64 currentTime){	if (!m_chpl_present)		return MP4_ERROR_NOT_ALLOWED;	DEBUGMSG (1, ("MP4Demux::Next, currentTime = %d\n", (RMint32)currentTime));	// find the current chapter we are on	RMint32 i, currentChapter = 0, nextChapter;		for (i=0; i<(RMint32)m_nchapters; i++)	{		DEBUGMSG (1, ("MP4Demux::Next, chapter = %d, time = %d\n", 			i, (RMint32)m_mp4Chapters[i].time));		if (m_mp4Chapters[i].time > currentTime)		{			if (i)			{				currentChapter = i - 1;				break;			}			else				currentChapter = 0;		}	}	if (i == (RMint32)m_nchapters)	{		DEBUGMSG (1, ("MP4Demux::Next, last chapter\n"));		nextChapter = 0;	}	else	{		DEBUGMSG (1, ("MP4Demux::Next, current chapter = %d\n", (RMint32)currentChapter));		nextChapter = currentChapter + 1;	}	DEBUGMSG (1, ("MP4Demux::Next, seeking to %d, %s\n", 		(RMint32)m_mp4Chapters[nextChapter].time,		m_mp4Chapters[nextChapter].name));	return Seek (m_mp4Chapters[nextChapter].time);}MP4_ERROR MP4Demux::Previous (RMint64 currentTime){	if (!m_chpl_present)		return MP4_ERROR_NOT_ALLOWED;	DEBUGMSG (1, ("MP4Demux::Previous, currentTime = %d\n", (RMint32)currentTime));	// find the current chapter we are on	RMint32 i, currentChapter = 0, prevChapter;		for (i=0; i<(RMint32)m_nchapters; i++)	{		DEBUGMSG (1, ("MP4Demux::Previous, chapter = %d, time = %d\n", 			i, (RMint32)m_mp4Chapters[i].time));		if (m_mp4Chapters[i].time > currentTime)		{			if (i)			{				currentChapter = i - 1;				break;			}			else				currentChapter = 0;		}	}	if (i == 0)	{		DEBUGMSG (1, ("MP4Demux::Previous, first chapter\n"));		return MP4_ERROR_NOT_ALLOWED;	}	else	{		DEBUGMSG (1, ("MP4Demux::Previous, current chapter = %d\n", (RMint32)currentChapter));		if (currentChapter == 0)		{			prevChapter = 0;		}		else		{			prevChapter = currentChapter - 1;		}	}	DEBUGMSG (1, ("MP4Demux::Previous, seeking to %d, %s\n", 		(RMint32)m_mp4Chapters[prevChapter].time,		m_mp4Chapters[prevChapter].name));	return Seek (m_mp4Chapters[prevChapter].time);}MP4_ERROR MP4Demux::RandomAccessPointsOnly (RMint64 currentTime, RMint32 direction){		if (m_video_stss.IsInitialized () == 0)		return MP4_ERROR_NOT_IMPLEMENTED;	if (direction == 0)	{		if (m_RandomAccessPointsOnly)		{			m_next_next_chunk = 0;			m_RandomAccessPointsOnly = 0;			m_State = MP4_DEMUX_STATE_GET_DATA;			return MP4_ERROR_NO_ERROR;		}								return MP4_ERROR_NOT_ALLOWED;	}	if (m_RandomAccessPointsOnly)	{		DEBUGMSG (1, ("RandomAccessPointsOnly: already in random access points only mode\n"));		if (m_videoDSILength)			m_CallbackTable.putDSI (0, 0, m_videoDSI, m_videoDSILength, (RMint64)m_tracktimescales[m_videoTrackIndex]/2, m_CallbackTable.context);		return MP4_ERROR_NO_ERROR;	}	m_CallbackTable.info (MP4_MSG_FLUSH_START, 0, m_CallbackTable.context);	while (m_State != MP4_DEMUX_STATE_GET_DATA)	{		if (Schedule () == MP4_ERROR_END_OF_FILE)			return MP4_ERROR_NOT_ALLOWED;	}	m_CallbackTable.info (MP4_MSG_FLUSH_END, 0, m_CallbackTable.context);	// a very cheap and easy way to convert time to sample ...	// it may not work in all cases though ...	RMuint32 samplecnt;	currentTime = currentTime * m_tracktimescales[m_videoTrackIndex] / 1000;	samplecnt = (RMuint32)(currentTime / m_video_stts_sample_delta);	DEBUGMSG (1, ("start random access at sample %lu\n", samplecnt));	// do a binary search looking for sample closest to samplecnt	RMuint32 istart, imiddle, iend, error;	RMuint32 random_access_point_sample_no;	istart = 0;	iend = m_video_stss.entrycount ();	imiddle = (istart + iend) / 2;	random_access_point_sample_no = 0;	while (1)	{					m_video_stss.seek (imiddle * 4);		random_access_point_sample_no = m_video_stss.get32 (&error) - 1;		m_video_stss.advance32 (&error);		if ((imiddle == istart) || (imiddle == iend) || (random_access_point_sample_no == samplecnt))		{							if (random_access_point_sample_no != samplecnt)			{				if (direction > 0)					imiddle = iend;				else					imiddle = istart;				m_video_stss.seek (imiddle * 4);				random_access_point_sample_no = m_video_stss.get32 (&error) - 1;				m_video_stss.advance32 (&error);			}			break;		}		if (samplecnt > random_access_point_sample_no)			istart = imiddle;		else 			iend = imiddle;		imiddle = (istart + iend) / 2;	}	ASSERT (random_access_point_sample_no >= 0);	m_currentRandomAccessPoint = random_access_point_sample_no;	m_RandomAccessPointsOnly = direction;	if (direction < 0)	{		m_video_stss.rewind32 (&error);		ASSERT (error == 0);	}	RMuint32 frame_no;	RMuint32 i;	RMuint32 first_chunk, samples_per_chunk, sample_description_index;	RMuint32 prev_samples_per_chunk, prev_first_chunk, frame_incr;	frame_no = 0;	m_video_sample_count = frame_no;	m_video_stsc.reset ();	prev_first_chunk = m_video_stsc.get32 (&error);	m_video_chunk_index = prev_first_chunk;	m_video_stsc.advance32 (&error);	ASSERT (error == 0);	prev_samples_per_chunk = m_video_stsc.get32 (&error);	m_video_samples_per_chunk = prev_samples_per_chunk;	m_samples_per_chunk = m_video_samples_per_chunk;	m_video_stsc.advance32 (&error);	ASSERT (error == 0);	sample_description_index = m_video_stsc.get32 (&error);	m_video_stsc.advance32 (&error);	ASSERT (error == 0);	for (i=0; i<m_video_stsc.entrycount (); i++)	{		 		first_chunk = m_video_stsc.get32 (&error);		frame_incr = prev_samples_per_chunk * (first_chunk - prev_first_chunk);		if ((frame_no + frame_incr) >= m_currentRandomAccessPoint)			break;		frame_no += frame_incr;		m_video_stsc.advance32 (&error);		ASSERT (error == 0);		samples_per_chunk = m_video_stsc.get32 (&error);		m_video_stsc.advance32 (&error);		ASSERT (error == 0);		sample_description_index = m_video_stsc.get32 (&error);		m_video_stsc.advance32 (&error);		ASSERT (error == 0);				prev_first_chunk = first_chunk;		prev_samples_per_chunk = samples_per_chunk;	}	m_video_sample_count = frame_no;	m_video_chunk_index = prev_first_chunk;	m_video_samples_per_chunk = prev_samples_per_chunk;	m_samples_per_chunk = prev_samples_per_chunk;	if (m_videoDSILength)		m_CallbackTable.putDSI (0, 0, m_videoDSI, m_videoDSILength, (RMint64)m_tracktimescales[m_videoTrackIndex]/2, m_CallbackTable.context);	m_next_next_chunk = 0;	m_pRandomAccessData = 0;	m_State = MP4_RANDOM_ACCESS_ONLY;	m_RandomAccessState = PROCESS_CURRENT_RANDOM_ACCESS_POINT;	return MP4_ERROR_NO_ERROR;}RMint32 MP4Demux::GetNumberOfAudioStreams (){	return m_naudioStreams;}RMint32 MP4Demux::GetNumberOfSubpictureStreams (){	return m_nspStreams;}MP4_ERROR MP4Demux::videoSeek (RMuint64 position_in_ms, RMuint32 *fileoffset){	m_video_stco.reset ();	m_video_stts.reset ();	m_video_ctts.reset ();	m_video_stsz.reset ();	m_video_stsc.reset ();	m_video_stss.reset ();	m_video_chunk_index = 1;	m_video_samples_per_chunk = 1;	m_video_sample_count = 0;	m_video_stts_sample_delta_count = 0;	m_video_ctts_sample_delta_count = 0;	m_video_ctts_sample_delta = 0;	m_videoTime = 0;	m_samples_per_chunk = 0;	m_chunkFlags = 0;	m_total_chunk_size = 0;	RMuint32 frame_no, chunk_offset;	RMuint32 error;	RMuint32 i, j;	RMuint32 first_chunk, samples_per_chunk, sample_description_index;	RMuint32 prev_samples_per_chunk, prev_first_chunk, frame_incr;	RMuint32 sample_delta, sync_sample;	RMuint64 time;	// seek to the correct stsc and stts table position	time = position_in_ms * m_tracktimescales[m_videoTrackIndex] / 1000;	m_video_stts_sample_delta_count = 0;	frame_no = 0;	prev_first_chunk = 1;	sample_delta = 0;	sync_sample = 0;	ASSERT (m_video_stsc.IsInitialized ());	for (i=0; i<m_video_stsc.entrycount (); i++)	{		 		first_chunk = m_video_stsc.get32 (&error);		m_video_stsc.advance32 (&error);		ASSERT (error == 0);		samples_per_chunk = m_video_stsc.get32 (&error);		m_video_stsc.advance32 (&error);		ASSERT (error == 0);		sample_description_index = m_video_stsc.get32 (&error);		m_video_stsc.advance32 (&error);		ASSERT (error == 0);		frame_incr = prev_samples_per_chunk * (first_chunk - prev_first_chunk);		frame_no += frame_incr;		// calculate the time of this frame to compare it to the requested time		if (m_video_stts.entrycount () == 0)		{			if (m_video_stts_sample_delta_count == 0)			{				m_video_stts_sample_delta_count = m_video_stts.get32 (&error);				m_video_stts.advance32 (&error);				ASSERT (error == 0);				sample_delta = m_video_stts.get32 (&error);				m_video_stts.advance32 (&error);				ASSERT (error == 0);				ASSERT (sample_delta);			}			ASSERT (sample_delta);			m_videoTime += (frame_incr * sample_delta);		}		else		{			for (j=0; j<frame_incr; j++)			{				if (m_video_stts_sample_delta_count == 0)				{					m_video_stts_sample_delta_count = m_video_stts.get32 (&error);					m_video_stts.advance32 (&error);					ASSERT (error == 0);					sample_delta = m_video_stts.get32 (&error);					m_video_stts.advance32 (&error);					ASSERT (error == 0);					ASSERT (sample_delta);				}				m_videoTime += sample_delta;				m_video_stts_sample_delta_count--;			}		}		if (m_videoTime >= time)		{			m_video_stsc.seek (i * 12);			m_video_samples_per_chunk = samples_per_chunk;			m_video_chunk_index = first_chunk;			m_video_sample_count = frame_no;			break;		}		prev_first_chunk = first_chunk;		prev_samples_per_chunk = samples_per_chunk;	}	ASSERT (i < m_video_stsc.entrycount ());	// seek to the correct ctts table position	if (m_video_ctts.IsInitialized ())	{		RMuint32 i, j, framecnt, n;		framecnt = 0;		error = 0;		for (i=0; i<m_video_ctts.entrycount (); i++)		{			n = m_video_ctts_sample_delta_count = m_video_ctts.get32 (&error);			m_video_ctts.advance32 (&error);			ASSERT (error == 0);			m_video_ctts_sample_delta = m_video_ctts.get32 (&error);			m_video_ctts.advance32 (&error);			ASSERT (error == 0);						for (j=0; j<n; j++)			{									m_video_ctts_sample_delta_count--;				framecnt++;				if (framecnt == frame_no)				{					goto video_ctts_table_finished;				}								}						}		ASSERT (0);	}video_ctts_table_finished:	// seek to the correct stsz table position	ASSERT (m_video_stsz.IsInitialized ());	if (m_video_sample_size == 0)		m_video_stsz.seek (frame_no * 4);	// seek to the correct stco table offset	ASSERT (m_video_stco.IsInitialized ());	ASSERT (m_video_chunk_index);	m_video_stco.seek ((m_video_chunk_index - 1) * 4);	chunk_offset = m_video_stco.get32 (&error);	DEBUGMSG (1, ("-------------------------\n"));	DEBUGMSG (1, ("VIDEO SEEK (fast method):\n"));	DEBUGMSG (1, ("m_video_chunk_index: %lu\n", m_video_chunk_index));	DEBUGMSG (1, ("m_video_samples_per_chunk: %lu\n", m_video_samples_per_chunk));	DEBUGMSG (1, ("m_video_sample_count: %lu\n", m_video_sample_count));	DEBUGMSG (1, ("m_video_stts_sample_delta_count: %lu\n", m_video_stts_sample_delta_count));	DEBUGMSG (1, ("m_video_ctts_sample_delta_count: %lu\n", m_video_ctts_sample_delta_count));	DEBUGMSG (1, ("m_video_ctts_sample_delta: %lu\n", m_video_ctts_sample_delta));	DEBUGMSG (1, ("m_videoTime: %lu\n", m_videoTime));	DEBUGMSG (1, ("stco: %lu, %lu\n", m_video_stco.tell (), m_video_stco.get32 (&error)));	DEBUGMSG (1, ("stts: %lu, %lu\n", m_video_stts.tell (), m_video_stts.get32 (&error)));	DEBUGMSG (1, ("ctts: %lu, %lu\n", m_video_ctts.tell (), m_video_ctts.get32 (&error)));	DEBUGMSG (1, ("stsz: %lu, %lu\n", m_video_stsz.tell (), m_video_stsz.get32 (&error)));	DEBUGMSG (1, ("stsc: %lu, %lu\n", m_video_stsc.tell (), m_video_stsc.get32 (&error)));	DEBUGMSG (1, ("-------------------------\n"));	*fileoffset = chunk_offset;	return MP4_ERROR_NO_ERROR;	// the code below is a brute force methos to do seek,	// it is really slow, but good for debugging if you want to check the results of	// the above code	m_video_stco.reset ();	m_video_stts.reset ();	m_video_ctts.reset ();	m_video_stsz.reset ();	m_video_stsc.reset ();	m_video_chunk_index = 1;	m_video_samples_per_chunk = 1;	m_video_sample_count = 0;	m_video_stts_sample_delta_count = 0;	m_video_ctts_sample_delta_count = 0;	m_video_ctts_sample_delta = 0;	m_videoTime = 0;	m_samples_per_chunk = 0;	m_chunkFlags = 0;	m_total_chunk_size = 0;	RMuint32 chunk_length, first_entry;	RMuint32 percent0, percent1;	percent0 = (RMuint32)-1;	while (1)	{		chunk_offset = m_video_stco.get32 (&error);		if (error)

⌨️ 快捷键说明

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