void xtr_oggvorbis_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *, int64_t, int64_t, int64_t, int64_t, bool, bool, bool) { m_content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK); ogg_packet op; op.packet = frame->get_buffer(); op.bytes = frame->get_size(); int64_t this_block_size = vorbis_packet_blocksize(&m_vorbis_info, &op); if (-1 != m_previous_block_size) { m_queued_granulepos = m_samples; m_samples += (this_block_size + m_previous_block_size) / 4; } m_previous_end = m_samples * 1000000000 / m_sfreq; m_previous_block_size = this_block_size; queue_frame(frame, 0); }
static std::shared_ptr<std::vector<std::string> > extract_vorbis_comments(const memory_cptr &mem) { std::shared_ptr<std::vector<std::string> > comments(new std::vector<std::string>); mm_mem_io_c in(mem->get_buffer(), mem->get_size()); uint32_t i, n, len; try { in.skip(7); // 0x03 "vorbis" n = in.read_uint32_le(); // vendor_length in.skip(n); // vendor_string n = in.read_uint32_le(); // user_comment_list_length comments->reserve(n); for (i = 0; i < n; i++) { len = in.read_uint32_le(); memory_cptr buffer(new memory_c((unsigned char *)safemalloc(len + 1), len + 1)); if (in.read(buffer->get_buffer(), len) != len) throw false; comments->push_back(std::string((char *)buffer->get_buffer(), len)); } } catch(...) { } return comments; }
void xtr_ivf_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *, int64_t timecode, int64_t, int64_t, int64_t, bool, bool, bool) { m_content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK); uint64_t frame_number = timecode * m_frame_rate_num / m_frame_rate_den / 1000000000ull; mxverb(2, boost::format("timecode %1% num %2% den %3% frame_number %4% calculated back %5%\n") % timecode % m_frame_rate_num % m_frame_rate_den % frame_number % (frame_number * 1000000000ull * m_frame_rate_den / m_frame_rate_num)); ivf::frame_header_t frame_header; put_uint32_le(&frame_header.frame_size, frame->get_size()); put_uint32_le(&frame_header.timestamp, frame_number); m_out->write(&frame_header, sizeof(frame_header)); m_out->write(frame->get_buffer(), frame->get_size()); ++m_frame_count; }
void header_removal_compressor_c::compress(memory_cptr &buffer) { if (!m_bytes.is_set() || (0 == m_bytes->get_size())) return; size_t size = m_bytes->get_size(); if (buffer->get_size() < size) throw mtx::compression_x(boost::format(Y("Header removal compression not possible because the buffer contained %1% bytes " "which is less than the size of the headers that should be removed, %2%.")) % buffer->get_size() % size); unsigned char *buffer_ptr = buffer->get_buffer(); unsigned char *bytes_ptr = m_bytes->get_buffer(); if (memcmp(buffer_ptr, bytes_ptr, size)) { std::string b_buffer, b_bytes; size_t i; for (i = 0; size > i; ++i) { b_buffer += (boost::format(" %|1$02x|") % static_cast<unsigned int>(buffer_ptr[i])).str(); b_bytes += (boost::format(" %|1$02x|") % static_cast<unsigned int>(bytes_ptr[i])).str(); } throw mtx::compression_x(boost::format(Y("Header removal compression not possible because the buffer did not start with the bytes that should be removed. " "Wanted bytes:%1%; found:%2%.")) % b_bytes % b_buffer); } size_t new_size = buffer->get_size() - size; if (buffer->is_free()) { memmove(buffer_ptr, buffer_ptr + size, new_size); buffer->set_size(new_size); } else buffer = clone_memory(buffer_ptr + size, new_size); }
size_t mm_io_c::write(const memory_cptr &buffer, size_t size, size_t offset) { size = std::min(buffer->get_size() - offset, size); if (write(buffer->get_buffer() + offset, size) != size) throw mtx::mm_io::end_of_file_x(); return size; }
void generic_packetizer_c::set_codec_private(memory_cptr const &buffer) { if (buffer && buffer->get_size()) { m_hcodec_private = buffer->clone(); if (m_track_entry) GetChild<KaxCodecPrivate>(*m_track_entry).CopyBuffer(static_cast<binary *>(m_hcodec_private->get_buffer()), m_hcodec_private->get_size()); } else m_hcodec_private.reset(); }
void header_removal_compressor_c::decompress(memory_cptr &buffer) { if (!m_bytes.is_set() || (0 == m_bytes->get_size())) return; memory_cptr new_buffer = memory_c::alloc(buffer->get_size() + m_bytes->get_size()); memcpy(new_buffer->get_buffer(), m_bytes->get_buffer(), m_bytes->get_size()); memcpy(new_buffer->get_buffer() + m_bytes->get_size(), buffer->get_buffer(), buffer->get_size()); buffer = new_buffer; }
memory_cptr header_removal_compressor_c::do_decompress(memory_cptr const &buffer) { if (!m_bytes || (0 == m_bytes->get_size())) return buffer; memory_cptr new_buffer = memory_c::alloc(buffer->get_size() + m_bytes->get_size()); memcpy(new_buffer->get_buffer(), m_bytes->get_buffer(), m_bytes->get_size()); memcpy(new_buffer->get_buffer() + m_bytes->get_size(), buffer->get_buffer(), buffer->get_size()); return new_buffer; }
void vc1_info_c::handle_sequence_header_packet(memory_cptr packet) { std::string checksum = create_checksum_info(packet); mxinfo(boost::format(Y("Sequence header at %1% size %2%%3%\n")) % m_stream_pos % packet->get_size() % checksum); m_seqhdr_found = vc1::parse_sequence_header(packet->get_buffer(), packet->get_size(), m_seqhdr); if (g_opt_sequence_headers) { if (m_seqhdr_found) dump_sequence_header(m_seqhdr); else mxinfo(Y(" parsing failed\n")); } }
void ssa_parser_c::decode_chars(unsigned char c1, unsigned char c2, unsigned char c3, unsigned char c4, memory_cptr &buffer, size_t bytes_to_add, size_t &allocated) { unsigned char bytes[3]; uint32_t value = ((c1 - 33) << 18) + ((c2 - 33) << 12) + ((c3 - 33) << 6) + (c4 - 33); bytes[2] = value & 0x0000ff; bytes[1] = (value & 0x00ff00) >> 8; bytes[0] = (value & 0xff0000) >> 16; if ((buffer->get_size() + bytes_to_add) > allocated) { int old_size = buffer->get_size(); allocated += 1024; buffer->resize(allocated); buffer->set_size(old_size); } memcpy(buffer->get_buffer() + buffer->get_size(), bytes, bytes_to_add); buffer->set_size(buffer->get_size() + bytes_to_add); }
std::string vc1_info_c::create_checksum_info(memory_cptr packet) { if (!g_opt_checksum) return ""; return (boost::format(Y(" checksum 0x%|1$08x|")) % calc_adler32(packet->get_buffer(), packet->get_size())).str(); }
void wav_pcm_demuxer_c::process(int64_t len) { if (0 >= len) return; m_ptzr->process(new packet_t(new memory_c(m_buffer->get_buffer(), len, false))); }
void vc1::es_parser_c::handle_entrypoint_packet(memory_cptr packet) { add_pre_frame_extra_data(packet); if (!m_raw_entrypoint.is_set()) m_raw_entrypoint = memory_cptr(packet->clone()); }
void vc1::es_parser_c::handle_packet(memory_cptr packet) { uint32_t marker = get_uint32_be(packet->get_buffer()); switch (marker) { case VC1_MARKER_SEQHDR: handle_sequence_header_packet(packet); break; case VC1_MARKER_ENTRYPOINT: handle_entrypoint_packet(packet); break; case VC1_MARKER_FRAME: handle_frame_packet(packet); break; case VC1_MARKER_SLICE: handle_slice_packet(packet); break; case VC1_MARKER_FIELD: handle_field_packet(packet); break; case VC1_MARKER_ENDOFSEQ: handle_end_of_sequence_packet(packet); break; default: handle_unknown_packet(marker, packet); break; } }
void vc1_info_c::handle_entrypoint_packet(memory_cptr packet) { std::string checksum = create_checksum_info(packet); mxinfo(boost::format(Y("Entrypoint at %1% size %2%%3%\n")) % m_stream_pos % packet->get_size() % checksum); if (!g_opt_entrypoints) return; if (!m_seqhdr_found) { mxinfo(Y(" No sequence header found yet; parsing not possible\n")); return; } vc1::entrypoint_t entrypoint; if (vc1::parse_entrypoint(packet->get_buffer(), packet->get_size(), entrypoint, m_seqhdr)) dump_entrypoint(entrypoint); }
uint32_t mm_io_c::read(memory_cptr &buffer, size_t size, int offset) { if (-1 == offset) offset = buffer->get_size(); if (buffer->get_size() <= (size + static_cast<size_t>(offset))) buffer->resize(size + offset); if (read(buffer->get_buffer() + offset, size) != size) throw mtx::mm_io::end_of_file_x(); buffer->set_size(size + offset); return size; }
void vc1_info_c::handle_frame_packet(memory_cptr packet) { std::string checksum = create_checksum_info(packet); mxinfo(boost::format(Y("Frame at %1% size %2%%3%\n")) % m_stream_pos % packet->get_size() % checksum); if (!g_opt_frames) return; if (!m_seqhdr_found) { mxinfo(Y(" No sequence header found yet; parsing not possible\n")); return; } vc1::frame_header_t frame_header; if (vc1::parse_frame_header(packet->get_buffer(), packet->get_size(), frame_header, m_seqhdr)) dump_frame_header(frame_header); }
void vc1::es_parser_c::handle_entrypoint_packet(memory_cptr packet) { if (!postpone_processing(packet)) add_pre_frame_extra_data(packet); if (!m_raw_entrypoint) m_raw_entrypoint = memory_cptr(packet->clone()); }
hdmv_textst_packetizer_c::hdmv_textst_packetizer_c(generic_reader_c *p_reader, track_info_c &p_ti, memory_cptr const &dialog_style_segment) : generic_packetizer_c{p_reader, p_ti} { m_ti.m_private_data = dialog_style_segment->clone(); set_track_type(track_subtitle); // set_default_compression_method(COMPRESSION_ZLIB); }
bool vc1::es_parser_c::postpone_processing(memory_cptr &packet) { if (m_seqhdr_found) return false; packet->grab(); m_unparsed_packets.push_back(packet); return true; }
std::vector<memory_cptr> unlace_memory_xiph(memory_cptr &buffer) { if (1 > buffer->get_size()) throw mtx::mem::lacing_x("Buffer too small"); std::vector<int> sizes; unsigned char *ptr = buffer->get_buffer(); unsigned char *end = buffer->get_buffer() + buffer->get_size(); size_t last_size = buffer->get_size(); size_t num_blocks = ptr[0] + 1; size_t i; ++ptr; for (i = 0; (num_blocks - 1) > i; ++i) { int size = 0; while ((ptr < end) && (*ptr == 255)) { size += 255; ++ptr; } if (ptr >= end) throw mtx::mem::lacing_x("End-of-buffer while reading the block sizes"); size += *ptr; ++ptr; sizes.push_back(size); last_size -= size; } sizes.push_back(last_size - (ptr - buffer->get_buffer())); std::vector<memory_cptr> blocks; for (i = 0; sizes.size() > i; ++i) { if ((ptr + sizes[i]) > end) throw mtx::mem::lacing_x("End-of-buffer while assigning the blocks"); blocks.push_back(memory_cptr(new memory_c(ptr, sizes[i], false))); ptr += sizes[i]; } return blocks; }
void analyze_header_removal_compressor_c::compress(memory_cptr &buffer) { ++m_packet_counter; if (!m_bytes.is_set()) { m_bytes = memory_cptr(buffer->clone()); return; } unsigned char *current = buffer->get_buffer(); unsigned char *saved = m_bytes->get_buffer(); size_t i, new_size = 0; for (i = 0; i < std::min(buffer->get_size(), m_bytes->get_size()); ++i, ++new_size) if (current[i] != saved[i]) break; m_bytes->set_size(new_size); }
void vc1::es_parser_c::handle_sequence_header_packet(memory_cptr packet) { flush_frame(); add_pre_frame_extra_data(packet); vc1::sequence_header_t seqhdr; if (!vc1::parse_sequence_header(packet->get_buffer(), packet->get_size(), seqhdr)) return; m_seqhdr_changed = !m_seqhdr_found || (packet->get_size() != m_raw_seqhdr->get_size()) || memcmp(packet->get_buffer(), m_raw_seqhdr->get_buffer(), packet->get_size()); memcpy(&m_seqhdr, &seqhdr, sizeof(vc1::sequence_header_t)); m_raw_seqhdr = memory_cptr(packet->clone()); m_seqhdr_found = true; if (!m_default_duration_forced && m_seqhdr.framerate_flag && (0 != m_seqhdr.framerate_num) && (0 != m_seqhdr.framerate_den)) m_default_duration = 1000000000ll * m_seqhdr.framerate_num / m_seqhdr.framerate_den; }
void vc1::es_parser_c::handle_frame_packet(memory_cptr packet) { flush_frame(); vc1::frame_header_t frame_header; if (!m_seqhdr_found || !vc1::parse_frame_header(packet->get_buffer(), packet->get_size(), frame_header, m_seqhdr)) return; m_current_frame = frame_cptr(new frame_t); m_current_frame->data = packet; m_current_frame->data->grab(); memcpy(&m_current_frame->header, &frame_header, sizeof(frame_header_t)); if (!m_timecodes.empty()) mxverb(2, boost::format("vc1::es_parser_c::handle_frame_packet: next provided timecode %1% next calculated timecode %2%\n") % format_timecode(m_timecodes.front()) % format_timecode(peek_next_calculated_timecode())); }
void lzo_compressor_c::compress(memory_cptr &buffer) { int size = buffer->get_size(); unsigned char *dst = (unsigned char *)safemalloc(size * 2); lzo_uint lzo_dstsize = size * 2; int result; if ((result = lzo1x_999_compress(buffer->get_buffer(), buffer->get_size(), dst, &lzo_dstsize, wrkmem)) != LZO_E_OK) mxerror(boost::format(Y("LZO compression failed. Result: %1%\n")) % result); int dstsize = lzo_dstsize; mxverb(3, boost::format("lzo_compressor_c: Compression from %1% to %2%, %3%%%\n") % size % dstsize % (dstsize * 100 / size)); raw_size += size; compressed_size += dstsize; items++; buffer = memory_cptr(new memory_c((unsigned char *)saferealloc(dst, dstsize), dstsize, true)); }
void xtr_oggtheora_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *, int64_t, int64_t, int64_t, int64_t, bool, bool, bool) { m_content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK); if (frame->get_size() && (0x00 == (frame->get_buffer()[0] & 0x40))) { m_keyframe_number += m_non_keyframe_number + 1; m_non_keyframe_number = 0; } else m_non_keyframe_number += 1; queue_frame(frame, (m_keyframe_number << m_theora_header.kfgshift) | (m_non_keyframe_number & ((1 << m_theora_header.kfgshift) - 1))); }
void xtr_oggkate_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *, int64_t timecode, int64_t, int64_t, int64_t, bool, bool, bool) { m_content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK); ogg_packet op; op.b_o_s = 0; op.e_o_s = (frame->get_size() == 1) && (frame->get_buffer()[0] == 0x7f); op.packetno = m_packetno; op.packet = frame->get_buffer(); op.bytes = frame->get_size(); /* we encode the backlink in the granulepos */ float f_timecode = timecode / 1000000000.0; int64_t g_backlink = 0; if (op.bytes >= static_cast<long>(1 + 3 * sizeof(int64_t))) g_backlink = get_uint64_le(op.packet + 1 + 2 * sizeof(int64_t)); float f_backlink = g_backlink * (float)m_kate_id_header.gden / m_kate_id_header.gnum; float f_base = f_timecode - f_backlink; float f_offset = f_timecode - f_base; int64_t g_base = (int64_t)(f_base * m_kate_id_header.gnum / m_kate_id_header.gden); int64_t g_offset = (int64_t)(f_offset * m_kate_id_header.gnum / m_kate_id_header.gden); op.granulepos = (g_base << m_kate_id_header.kfgshift) | g_offset; ogg_stream_packetin(&m_os, &op); flush_pages(); /* Kate is a data packet per page */ ++m_packetno; }
bool is_keyframe(memory_cptr const &buffer, codec_c::type_e codec) { // Remember: bit numbers start with the least significant bit. Bit 0 // == 1, bit 1 == 2 etc. if (!buffer || !buffer->get_size()) return false; auto data = buffer->get_buffer(); if (codec == codec_c::type_e::V_VP8) return (data[0] & 0x01) == 0x00; // VP9 // Bits 0, 1: frame marker, supposed to be 0x02 // Bit 2: version // Bit 3: show existing frame directly flag // Bit 4: frame type (0 means key frame) if ((data[0] & 0x04) == 0x04) return false; return (data[0] & 0x10) == 0x00; }
void xtr_base_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *, int64_t, int64_t, int64_t, int64_t, bool, bool, bool) { m_content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK); m_out->write(frame); m_bytes_written += frame->get_size(); }
void bzlib_compressor_c::compress(memory_cptr &buffer) { bz_stream c_stream; int size = buffer->get_size(); unsigned char *dst = (unsigned char *)safemalloc(size * 2); c_stream.bzalloc = NULL; c_stream.bzfree = NULL; c_stream.opaque = NULL; int result = BZ2_bzCompressInit(&c_stream, 9, 0, 30); if (BZ_OK != result) mxerror(boost::format(Y("BZ2_bzCompressInit() failed. Result: %1%\n")) % result); c_stream.next_in = (char *)buffer->get_buffer(); c_stream.next_out = (char *)dst; c_stream.avail_in = size; c_stream.avail_out = 2 * size; result = BZ2_bzCompress(&c_stream, BZ_FINISH); if (BZ_STREAM_END != result) mxerror(boost::format(Y("bzip2 compression failed. Result: %1%\n")) % result); BZ2_bzCompressEnd(&c_stream); int dstsize = 2 * size - c_stream.avail_out; mxverb(3, boost::format("bzlib_compressor_c: Compression from %1% to %2%, %3%%%\n") % size % dstsize % (dstsize * 100 / size)); raw_size += size; compressed_size += dstsize; items++; buffer = memory_cptr(new memory_c((unsigned char *)saferealloc(dst, dstsize), dstsize, true)); }