void xtr_avc_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { xtr_base_c::create_file(master, track); KaxCodecPrivate *priv = FindChild<KaxCodecPrivate>(&track); if (!priv) mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id); memory_cptr mpriv = decode_codec_private(priv); if (mpriv->get_size() < 6) mxerror(boost::format(Y("Track %1% CodecPrivate is too small.\n")) % m_tid); binary *buf = mpriv->get_buffer(); m_nal_size_size = 1 + (buf[4] & 3); size_t pos = 6; unsigned int numsps = buf[5] & 0x1f; size_t i; for (i = 0; (i < numsps) && (mpriv->get_size() > pos); ++i) if (!write_nal(buf, pos, mpriv->get_size(), 2)) break; if (mpriv->get_size() <= pos) return; unsigned int numpps = buf[pos++]; for (i = 0; (i < numpps) && (mpriv->get_size() > pos); ++i) write_nal(buf, pos, mpriv->get_size(), 2); }
void xtr_hevc_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { xtr_base_c::create_file(master, track); auto priv = FindChild<KaxCodecPrivate>(&track); if (!priv) mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id); auto mpriv = decode_codec_private(priv); if (mpriv->get_size() < 23) mxerror(boost::format(Y("Track %1% CodecPrivate is too small.\n")) % m_tid); auto buf = mpriv->get_buffer(); m_nal_size_size = 1 + (buf[21] & 3); // Parameter sets in this order: vps, sps, pps, sei auto num_parameter_sets = static_cast<unsigned int>(buf[22]); auto pos = static_cast<size_t>(23); while (num_parameter_sets && (mpriv->get_size() > (pos + 3))) { auto nal_unit_count = get_uint16_be(&buf[pos + 1]); pos += 3; while (nal_unit_count && (mpriv->get_size() > pos)) { if (!write_nal(buf, pos, mpriv->get_size(), 2)) return; --nal_unit_count; --num_parameter_sets; } } }
void xtr_avc_c::handle_frame(xtr_frame_t &f) { size_t pos = 0; binary *buf = (binary *)f.frame->get_buffer(); while (f.frame->get_size() > pos) if (!write_nal(buf, pos, f.frame->get_size(), m_nal_size_size)) return; }