📄 mp4.cpp
字号:
if (error) { m_State = MP4_DEMUX_STATE_END_OF_FILE; return MP4_ERROR_NO_ERROR; } RMuint32 prev_first_chunk, prev_samples_per_chunk, samples_per_chunk; frame_no = m_video_sample_count; prev_first_chunk = m_video_chunk_index; prev_samples_per_chunk = m_video_samples_per_chunk; while (1) { 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); if (error) { m_State = MP4_DEMUX_STATE_END_OF_FILE; return MP4_ERROR_NO_ERROR; } samples_per_chunk = m_video_stsc.get32 (&error); m_video_stsc.advance32 (&error); ASSERT (error == 0); if (error) { m_State = MP4_DEMUX_STATE_END_OF_FILE; return MP4_ERROR_NO_ERROR; } sample_description_index = m_video_stsc.get32 (&error); m_video_stsc.advance32 (&error); ASSERT (error == 0); if (error) { m_State = MP4_DEMUX_STATE_END_OF_FILE; return MP4_ERROR_NO_ERROR; } 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; m_RandomAccessState = PROCESS_CURRENT_RANDOM_ACCESS_POINT; break; case UPDATE_PREVIOUS_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_video_stss.rewind32 (&error); ASSERT (error == 0); m_currentRandomAccessPoint = m_video_stss.get32 (&error) - 1; if (error) { m_State = MP4_DEMUX_STATE_END_OF_FILE; return MP4_ERROR_NO_ERROR; } frame_no = m_video_sample_count; next_chunk = m_video_chunk_index; while (1) { rewind = 1; if (m_next_next_chunk) { ASSERT (m_next_next_chunk != next_chunk); frame_incr = m_samples_per_chunk * (m_next_next_chunk - next_chunk); if ((m_next_next_frame_no - frame_incr) < m_currentRandomAccessPoint) { first_chunk = next_chunk; samples_per_chunk = m_samples_per_chunk; frame_no = m_next_next_frame_no; rewind = 0; } } if (rewind) { m_video_stsc.rewind32 (&error); m_video_stsc.rewind32 (&error); m_video_stsc.rewind32 (&error); m_video_stsc.rewind32 (&error); m_video_stsc.rewind32 (&error); m_video_stsc.rewind32 (&error); ASSERT (error == 0); if (error) { m_State = MP4_DEMUX_STATE_END_OF_FILE; return MP4_ERROR_NO_ERROR; } first_chunk = m_video_stsc.get32 (&error); m_video_stsc.advance32 (&error); samples_per_chunk = m_video_stsc.get32 (&error); m_video_stsc.advance32 (&error); m_video_stsc.get32 (&error); m_video_stsc.advance32 (&error); frame_incr = samples_per_chunk * (next_chunk - first_chunk); } ASSERT (frame_incr > 0); ASSERT (frame_no >= (RMuint32)frame_incr); if ((frame_no - frame_incr) < m_currentRandomAccessPoint) { if (rewind) { m_next_next_chunk = next_chunk; m_next_next_frame_no = frame_no; } m_video_chunk_index = first_chunk; m_video_samples_per_chunk = samples_per_chunk; m_samples_per_chunk = samples_per_chunk; m_video_sample_count = frame_no - frame_incr; if (m_skipcount-- <= 0) { m_RandomAccessState = PROCESS_CURRENT_RANDOM_ACCESS_POINT; m_skipcount = m_skipcount_resetvalue; } break; } m_next_next_chunk = 0; next_chunk = first_chunk; frame_no -= frame_incr; } break; } return MP4_ERROR_NO_ERROR;}RMuint64 MP4Demux::Duration (){ ASSERT (m_mvhdTimeScale); if (m_mvhdTimeScale == 0) m_mvhdTimeScale = 1; return (RMuint64)((RMuint64)m_mvhdDuration * 1000 / (RMuint64)m_mvhdTimeScale);}MP4_ERROR MP4Demux::Seek (RMint64 position_in_ms){ RMuint32 video_present, audio_present, subpi_present; video_present = m_video_stco.IsInitialized () && m_video_stsz.IsInitialized () && m_video_stsc.IsInitialized (); audio_present = m_audio_stco[0].IsInitialized () && m_audio_stsz[0].IsInitialized () && m_audio_stsc[0].IsInitialized (); subpi_present = m_subpi_stco[0].IsInitialized () && m_subpi_stsz[0].IsInitialized () && m_subpi_stsc[0].IsInitialized (); if ((video_present == 0) && (audio_present == 0)) { ASSERT (0); return MP4_ERROR_NOT_ALLOWED; } 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); if (position_in_ms == 0) { RMint32 i; m_CallbackTable.info (MP4_MSG_SEEK_START, 0, m_CallbackTable.context); 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; for (i=0; i<MP4_MAX_AUDIOTRACKS; i++) { m_audio_stco[i].reset (); m_audio_stts[i].reset (); m_audio_ctts[i].reset (); m_audio_stsz[i].reset (); m_audio_stsc[i].reset (); m_audio_chunk_index[i] = 1; m_audio_samples_per_chunk[i] = 1; m_audio_sample_count[i] = 0; m_audio_stts_sample_delta_count[i] = 0; m_audio_ctts_sample_delta_count[i] = 0; m_audio_ctts_sample_delta[i] = 0; m_audioTime[i] = 0; } for (i=0; i<MP4_MAX_SUBPICTRACKS; i++) { m_subpi_stco[i].reset (); m_subpi_stts[i].reset (); m_subpi_stsz[i].reset (); m_subpi_stsc[i].reset (); m_subpi_chunk_index[i] = 1; m_subpi_samples_per_chunk[i] = 1; m_subpi_sample_count[i] = 0; m_subpi_stts_sample_delta_count[i] = 0; m_subpi_ctts_sample_delta_count[i] = 0; m_subpi_ctts_sample_delta[i] = 0; m_subpiTime[i] = 0; } m_samples_per_chunk = 0; m_chunkFlags = 0; m_total_chunk_size = 0; m_currentOffset = m_mdatpos; seek (m_currentOffset); if (m_videoDSILength) m_CallbackTable.putDSI (0, 0, m_videoDSI, m_videoDSILength, (RMint64)m_tracktimescales[m_videoTrackIndex]/2, m_CallbackTable.context); for (i=0; i<MP4_MAX_AUDIOTRACKS; i++) { if (m_audioDSILength[i]) m_CallbackTable.putDSI (1 | (i << 8), 0, m_audioDSI[i], m_audioDSILength[i], 0, m_CallbackTable.context); } for (i=0; i<MP4_MAX_SUBPICTRACKS; i++) { if (m_spDSILength) { SPU_DIMENSIONS spDimensions; ASSERT (m_subpiTrackIndex[i] != -1); ASSERT (m_subpiTrackIndex[i] < MP4_MAX_TRACKS); if (m_subpiTrackIndex[i] != -1) { spDimensions.spWidth = m_spWidth[m_subpiTrackIndex[i]]; spDimensions.spHeight = m_spHeight[m_subpiTrackIndex[i]]; m_CallbackTable.info (MP4_MSG_SPU_DIMENSIONS, &spDimensions, m_CallbackTable.context); m_CallbackTable.putDSI (2 | (i << 8), 0, m_spDSI[i], m_spDSILength[i], 0, m_CallbackTable.context); } } else if (i < m_nspStreams) { SPU_DIMENSIONS spDimensions; spDimensions.spWidth = 0; spDimensions.spHeight = 0; m_CallbackTable.info (MP4_MSG_SPU_DIMENSIONS, &spDimensions, m_CallbackTable.context); m_CallbackTable.putDSI (2 | (i << 8), 0, 0, 0, 0, m_CallbackTable.context); } } m_firstVideoChunk = 1; return MP4_ERROR_NO_ERROR; } RMuint32 videoOffset, audioOffset, subpiOffset; MP4_ERROR mp4_error; if ((video_present) && (audio_present)) { RMint64 maxtime; maxtime = (RMint64)m_trackdurations[m_videoTrackIndex] * (RMint64)1000 / (RMint64)m_tracktimescales[m_videoTrackIndex]; if (maxtime > 1000) maxtime -= 1000; DEBUGMSG (1, ("duration of video track: %d ms\n", (RMint32)maxtime)); DEBUGMSG (1, ("seek to: %d ms\n", (RMint32)position_in_ms)); if (position_in_ms >= maxtime) { DEBUGMSG (1, ("seek to time exceeds duration\n")); return MP4_ERROR_NOT_ALLOWED; } ASSERT (m_CallbackTable.info); m_CallbackTable.info (MP4_MSG_SEEK_START, 0, m_CallbackTable.context);// int t0, t1;// t0 = gettime (); mp4_error = videoSeek (position_in_ms, &videoOffset);// t1 = gettime ();// printf ("videoSeek took %d ms\n", t1-t0); DEBUGMSG (1, ("videoOffset: %d\n", (RMint32)videoOffset)); ASSERT (mp4_error == MP4_ERROR_NO_ERROR);// t0 = gettime (); mp4_error = audioSeek (videoOffset, &audioOffset, 1);// t1 = gettime ();// printf ("audioSeek took %d ms\n", t1-t0); if (mp4_error == MP4_ERROR_NO_ERROR) { DEBUGMSG (1, ("audioOffset: %d\n", (RMint32)audioOffset)); ASSERT (mp4_error == MP4_ERROR_NO_ERROR); m_currentOffset = MP4_MIN (videoOffset, audioOffset); } else { // the video stream is longer than the audio stream ASSERT (mp4_error == MP4_ERROR_FILE_TOO_SHORT); DEBUGMSG (1, ("audio stream is shorter than video stream\n")); m_currentOffset = videoOffset; } DEBUGMSG (1, ("m_currentOffset: %d\n", (RMint32)m_currentOffset)); if (subpi_present) {// t0 = gettime (); mp4_error = subpiSeek (m_currentOffset, &subpiOffset, 1);// t1 = gettime ();// printf ("subpiSeek took %d ms\n", t1-t0); ASSERT (mp4_error == MP4_ERROR_NO_ERROR); ASSERT (subpiOffset >= m_currentOffset); } } else if (video_present) { RMint64 maxtime; maxtime = (RMint64)m_trackdurations[m_videoTrackIndex] * (RMint64)1000 / (RMint64)m_tracktimescales[m_videoTrackIndex]; if (maxtime > 1000) maxtime -= 1000; DEBUGMSG (1, ("duration of video track: %d ms\n", (RMint32)maxtime)); DEBUGMSG (1, ("seek to: %d ms\n", (RMint32)position_in_ms)); if (position_in_ms >= maxtime) { DEBUGMSG (1, ("seek to time exceeds duration\n")); return MP4_ERROR_NOT_ALLOWED; } ASSERT (m_CallbackTable.info); m_CallbackTable.info (MP4_MSG_SEEK_START, 0, m_CallbackTable.context); mp4_error = videoSeek (position_in_ms, &videoOffset); ASSERT (mp4_error == MP4_ERROR_NO_ERROR); m_currentOffset = videoOffset; if (subpi_present) { mp4_error = subpiSeek (m_currentOffset, &subpiOffset, 1); ASSERT (mp4_error == MP4_ERROR_NO_ERROR); ASSERT (subpiOffset >= m_currentOffset); } } else if (audio_present) { RMint64 maxtime; maxtime = (RMint64)m_trackdurations[m_audioTrackIndex[m_currentAudioTrack]] * (RMint64)1000 / (RMint64)m_tracktimescales[m_audioTrackIndex[m_currentAudioTrack]]; if (maxtime > 1000) maxtime -= 1000; DEBUGMSG (1, ("duration of audio track: %d ms\n", (RMint32)maxtime)); DEBUGMSG (1, ("seek to: %d ms\n", (RMint32)position_in_ms)); if (position_in_ms >= maxtime) { DEBUGMSG (1, ("seek to time exceeds duration\n")); return MP4_ERROR_NOT_ALLOWED; } ASSERT (m_CallbackTable.info); m_CallbackTable.info (MP4_MSG_SEEK_START, 0, m_CallbackTable.context); mp4_error = audioSeek (position_in_ms, &audioOffset, 0); ASSERT (mp4_error == MP4_ERROR_NO_ERROR); m_currentOffset = audioOffset; if (subpi_present) { mp4_error = subpiSeek (m_currentOffset, &subpiOffset, 1); ASSERT (mp4_error == MP4_ERROR_NO_ERROR); ASSERT (subpiOffset >= m_currentOffset); } } else { ASSERT (0); return MP4_ERROR_NOT_ALLOWED; } seek (m_currentOffset); if (m_videoDSILength) m_CallbackTable.putDSI (0, 0, m_videoDSI, m_videoDSILength, (RMint64)m_tracktimescales[m_videoTrackIndex]/2, m_CallbackTable.context); RMuint32 i; for (i=0; i<MP4_MAX_AUDIOTRACKS; i++) { if (m_audioDSILength[i]) m_CallbackTable.putDSI (1 | (i << 8), 0, m_audioDSI[i], m_audioDSILength[i], 0, m_CallbackTable.context); } for (i=0; i<MP4_MAX_SUBPICTRACKS; i++) { if (m_spDSILength[i]) { SPU_DIMENSIONS spDimensions; ASSERT (m_subpiTrackIndex[i] != -1); ASSERT (m_subpiTrackIndex[i] < MP4_MAX_TRACKS); if (m_subpiTrackIndex[i] != -1) { spDimensions.spWidth = m_spWidth[m_subpiTrackIndex[i]]; spDimensions.spHeight = m_spHeight[m_subpiTrackIndex[i]]; m_CallbackTable.info (MP4_MSG_SPU_DIMENSIONS, &spDimensions, m_CallbackTable.context); m_CallbackTable.putDSI (2 | (i << 8), 0, m_spDSI[i], m_spDSILength[i], 0, m_CallbackTable.context); } } else if ((RMint32)i < m_nspStreams) { SPU_DIMENSIONS spDimensions; spDimensions.spWidth = 0; spDimensions.spHeight = 0; m_CallbackTable.info (MP4_MSG_SPU_DIMENSIONS, &spDimensions, m_CallbackTable.context); m_CallbackTable.putDSI (2 | (i << 8), 0, 0, 0, 0, m_CallbackTable.context); } } m_firstVideoChunk = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -