int hdmv_textst_packetizer_c::process(packet_cptr packet) { if ((packet->data->get_size() < 13) || (static_cast<mtx::hdmv_textst::segment_type_e>(packet->data->get_buffer()[0]) != mtx::hdmv_textst::dialog_presentation_segment)) return FILE_STATUS_MOREDATA; auto buf = packet->data->get_buffer(); auto start_pts = timestamp_c::mpeg((static_cast<int64_t>(buf[3] & 1) << 32) | get_uint32_be(&buf[4])); auto end_pts = timestamp_c::mpeg((static_cast<int64_t>(buf[8] & 1) << 32) | get_uint32_be(&buf[9])); if (!packet->has_timestamp()) packet->timestamp = start_pts.to_ns(); if (!packet->has_duration()) packet->duration = (end_pts - start_pts).abs().to_ns(); packet->duration_mandatory = true; add_packet(packet); return FILE_STATUS_MOREDATA; }
void generic_packetizer_c::add_packet2(packet_cptr pack) { if (pack->has_discard_padding()) set_required_matroska_version(4); pack->timecode = ADJUST_TIMECODE(pack->timecode); if (pack->has_bref()) pack->bref = ADJUST_TIMECODE(pack->bref); if (pack->has_fref()) pack->fref = ADJUST_TIMECODE(pack->fref); if (pack->has_duration()) { pack->duration = static_cast<int64_t>(pack->duration * m_ti.m_tcsync.numerator / m_ti.m_tcsync.denominator); if (pack->has_discard_padding()) pack->duration -= std::min(pack->duration, pack->discard_padding.to_ns()); } if ((2 > m_htrack_min_cache) && pack->has_fref()) { set_track_min_cache(2); rerender_track_headers(); } else if ((1 > m_htrack_min_cache) && pack->has_bref()) { set_track_min_cache(1); rerender_track_headers(); } if (0 > pack->timecode) return; // 'timecode < safety_last_timecode' may only occur for B frames. In this // case we have the coding order, e.g. IPB1B2 and the timecodes // I: 0, P: 120, B1: 40, B2: 80. if (!m_relaxed_timecode_checking && (pack->timecode < m_safety_last_timecode) && (0 > pack->fref) && hack_engaged(ENGAGE_ENABLE_TIMECODE_WARNING)) { if (track_audio == m_htrack_type) { int64_t needed_timecode_offset = m_safety_last_timecode + m_safety_last_duration - pack->timecode; m_correction_timecode_offset += needed_timecode_offset; pack->timecode += needed_timecode_offset; if (pack->has_bref()) pack->bref += needed_timecode_offset; if (pack->has_fref()) pack->fref += needed_timecode_offset; mxwarn_tid(m_ti.m_fname, m_ti.m_id, boost::format(Y("The current packet's timecode is smaller than that of the previous packet. " "This usually means that the source file is a Matroska file that has not been created 100%% correctly. " "The timecodes of all packets will be adjusted by %1%ms in order not to lose any data. " "This may throw audio/video synchronization off, but that can be corrected with mkvmerge's \"--sync\" option. " "If you already use \"--sync\" and you still get this warning then do NOT worry -- this is normal. " "If this error happens more than once and you get this message more than once for a particular track " "then either is the source file badly mastered, or mkvmerge contains a bug. " "In this case you should contact the author Moritz Bunkus <*****@*****.**>.\n")) % ((needed_timecode_offset + 500000) / 1000000)); } else mxwarn_tid(m_ti.m_fname, m_ti.m_id, boost::format("generic_packetizer_c::add_packet2: timecode < last_timecode (%1% < %2%). %3%\n") % format_timestamp(pack->timecode) % format_timestamp(m_safety_last_timecode) % BUGMSG); } m_safety_last_timecode = pack->timecode; m_safety_last_duration = pack->duration; pack->timecode_before_factory = pack->timecode; m_packet_queue.push_back(pack); if (!m_timestamp_factory || (TFA_IMMEDIATE == m_timestamp_factory_application_mode)) apply_factory_once(pack); else apply_factory(); }