mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2025-01-17 15:42:10 +00:00
AVC/h.264 common: refactor timestamping code
This commit is contained in:
parent
5c54f887f7
commit
36b7a6514e
@ -987,6 +987,7 @@ mpeg4::p10::avc_es_parser_c::avc_es_parser_c()
|
|||||||
, m_b_frames_since_keyframe(false)
|
, m_b_frames_since_keyframe(false)
|
||||||
, m_par_found(false)
|
, m_par_found(false)
|
||||||
, m_max_timecode(0)
|
, m_max_timecode(0)
|
||||||
|
, m_previous_frame_start_in_display_order{}
|
||||||
, m_stream_position(0)
|
, m_stream_position(0)
|
||||||
, m_parsed_position(0)
|
, m_parsed_position(0)
|
||||||
, m_have_incomplete_frame(false)
|
, m_have_incomplete_frame(false)
|
||||||
@ -1259,6 +1260,7 @@ mpeg4::p10::avc_es_parser_c::handle_slice_nalu(memory_cptr &nalu) {
|
|||||||
|| ( is_i_slice
|
|| ( is_i_slice
|
||||||
&& ( (m_debug_keyframe_detection && !m_b_frames_since_keyframe)
|
&& ( (m_debug_keyframe_detection && !m_b_frames_since_keyframe)
|
||||||
|| (NALU_TYPE_IDR_SLICE == si.nalu_type)));
|
|| (NALU_TYPE_IDR_SLICE == si.nalu_type)));
|
||||||
|
m_incomplete_frame.m_type = m_incomplete_frame.m_keyframe ? 'I' : is_b_slice ? 'B' : 'P';
|
||||||
m_recovery_point_valid = false;
|
m_recovery_point_valid = false;
|
||||||
|
|
||||||
if (m_incomplete_frame.m_keyframe) {
|
if (m_incomplete_frame.m_keyframe) {
|
||||||
@ -1267,8 +1269,11 @@ mpeg4::p10::avc_es_parser_c::handle_slice_nalu(memory_cptr &nalu) {
|
|||||||
if (!si.field_pic_flag || !si.bottom_field_flag)
|
if (!si.field_pic_flag || !si.bottom_field_flag)
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
} else
|
} else if (is_b_slice)
|
||||||
m_b_frames_since_keyframe |= is_b_slice;
|
m_b_frames_since_keyframe = true;
|
||||||
|
|
||||||
|
// else if (!si.field_pic_flag || !si.bottom_field_flag)
|
||||||
|
// cleanup();
|
||||||
|
|
||||||
m_incomplete_frame.m_data = create_nalu_with_size(nalu, true);
|
m_incomplete_frame.m_data = create_nalu_with_size(nalu, true);
|
||||||
m_have_incomplete_frame = true;
|
m_have_incomplete_frame = true;
|
||||||
@ -1712,7 +1717,6 @@ mpeg4::p10::avc_es_parser_c::cleanup() {
|
|||||||
|
|
||||||
frames_begin = m_frames.begin();
|
frames_begin = m_frames.begin();
|
||||||
frames_end = m_frames.end();
|
frames_end = m_frames.end();
|
||||||
previous_frame_itr = frames_begin;
|
|
||||||
|
|
||||||
// This may be wrong but is needed for mkvmerge to work correctly
|
// This may be wrong but is needed for mkvmerge to work correctly
|
||||||
// (cluster_helper etc).
|
// (cluster_helper etc).
|
||||||
@ -1721,11 +1725,15 @@ mpeg4::p10::avc_es_parser_c::cleanup() {
|
|||||||
m_first_cleanup = false;
|
m_first_cleanup = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (frame_itr = frames_begin; frames_end != frame_itr; ++frame_itr) {
|
// mxinfo(boost::format("frame order calculation\n"));
|
||||||
if (frames_begin != frame_itr)
|
|
||||||
frame_itr->m_ref1 = previous_frame_itr->m_start - frame_itr->m_start;
|
|
||||||
|
|
||||||
previous_frame_itr = frame_itr;
|
for (frame_itr = frames_begin; frames_end != frame_itr; ++frame_itr) {
|
||||||
|
// mxinfo(boost::format(" type %4% decode order %1% presentation order %2% timestamp %3%\n") % frame_itr->m_decode_order % frame_itr->m_presentation_order % format_timecode(frame_itr->m_start) % frame_itr->m_type);
|
||||||
|
|
||||||
|
if (!frame_itr->is_i_frame() && (frames_begin != frame_itr))
|
||||||
|
frame_itr->m_ref1 = m_previous_frame_start_in_display_order - frame_itr->m_start;
|
||||||
|
|
||||||
|
m_previous_frame_start_in_display_order = frame_itr->m_start;
|
||||||
m_duration_frequency[frame_itr->m_end - frame_itr->m_start]++;
|
m_duration_frequency[frame_itr->m_end - frame_itr->m_start]++;
|
||||||
|
|
||||||
if (frame_itr->m_si.field_pic_flag)
|
if (frame_itr->m_si.field_pic_flag)
|
||||||
|
@ -161,6 +161,7 @@ struct avc_frame_t {
|
|||||||
bool m_keyframe, m_has_provided_timecode;
|
bool m_keyframe, m_has_provided_timecode;
|
||||||
slice_info_t m_si;
|
slice_info_t m_si;
|
||||||
int m_presentation_order, m_decode_order;
|
int m_presentation_order, m_decode_order;
|
||||||
|
char m_type;
|
||||||
bool m_order_calculated;
|
bool m_order_calculated;
|
||||||
|
|
||||||
avc_frame_t() {
|
avc_frame_t() {
|
||||||
@ -180,11 +181,24 @@ struct avc_frame_t {
|
|||||||
m_has_provided_timecode = false;
|
m_has_provided_timecode = false;
|
||||||
m_presentation_order = 0;
|
m_presentation_order = 0;
|
||||||
m_decode_order = 0;
|
m_decode_order = 0;
|
||||||
|
m_type = '?';
|
||||||
m_order_calculated = false;
|
m_order_calculated = false;
|
||||||
m_data.reset();
|
m_data.reset();
|
||||||
|
|
||||||
m_si.clear();
|
m_si.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_i_frame() const {
|
||||||
|
return 'I' == m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_p_frame() const {
|
||||||
|
return 'P' == m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_b_frame() const {
|
||||||
|
return 'B' == m_type;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class nalu_size_length_x: public mtx::exception {
|
class nalu_size_length_x: public mtx::exception {
|
||||||
@ -249,7 +263,7 @@ protected:
|
|||||||
std::deque<avc_frame_t> m_frames, m_frames_out;
|
std::deque<avc_frame_t> m_frames, m_frames_out;
|
||||||
std::deque<int64_t> m_provided_timecodes;
|
std::deque<int64_t> m_provided_timecodes;
|
||||||
std::deque<uint64_t> m_provided_stream_positions;
|
std::deque<uint64_t> m_provided_stream_positions;
|
||||||
int64_t m_max_timecode;
|
int64_t m_max_timecode, m_previous_frame_start_in_display_order;
|
||||||
std::map<int64_t, int64_t> m_duration_frequency;
|
std::map<int64_t, int64_t> m_duration_frequency;
|
||||||
|
|
||||||
std::vector<memory_cptr> m_sps_list, m_pps_list, m_extra_data;
|
std::vector<memory_cptr> m_sps_list, m_pps_list, m_extra_data;
|
||||||
|
Loading…
Reference in New Issue
Block a user