int mm_io_c::write_uint32_be(uint32_t value) { uint32_t buffer; put_uint32_be(&buffer, value); return write(&buffer, sizeof(uint32_t)); }
std::string fourcc_c::str() const { char buffer[4]; put_uint32_be(buffer, m_value); for (auto idx = 0; 4 > idx; ++idx) buffer[idx] = 32 <= buffer[idx] ? buffer[idx] : '?'; return std::string{buffer, 4}; }
std::string fourcc_to_string(uint32_t fourcc) { unsigned char buffer[4], idx; put_uint32_be(buffer, fourcc); for (idx = 0; 4 > idx; ++idx) if (buffer[idx] < ' ') buffer[idx] = ' '; return std::string(reinterpret_cast<char *>(buffer), 4); }
std::string fourcc_c::description() const { static auto s_id_fmt = boost::format("0x%|1$08x| \"%2%%3%%4%%5%\""); static auto s_name_fmt = boost::format(": %1%"); unsigned char buffer[4]; put_uint32_be(buffer, m_value); auto result = (s_id_fmt % m_value % C(0) % C(1) % C(2) % C(3)).str(); auto codec = codec_c::look_up(*this); if (codec.valid()) result += (s_name_fmt % codec.get_name()).str(); return result; }
void xtr_alac_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { init_content_decoder(track); auto channels = kt_get_a_channels(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); m_priv = decode_codec_private(priv); if (m_priv->get_size() != sizeof(alac::codec_config_t)) mxerror(boost::format(Y("ALAC private data size mismatch\n"))); xtr_base_c::create_file(master, track); m_out->write(std::string{"caff"}); // mFileType m_out->write_uint16_be(1); // mFileVersion m_out->write_uint16_be(0); // mFileFlags m_out->write(std::string{"desc"}); // Audio Description chunk m_out->write_uint64_be(32ULL); // mChunkSize m_out->write_double(static_cast<int>(kt_get_a_sfreq(track))); // mSampleRate m_out->write(std::string{"alac"}); // mFormatID m_out->write_uint32_be(0); // mFormatFlags m_out->write_uint32_be(0); // mBytesPerPacket m_out->write_uint32_be(caf::defs::default_frames_per_packet); // mFramesPerPacket m_out->write_uint32_be(channels); // mChannelsPerFrame m_out->write_uint32_be(0); // mBitsPerChannel auto kuki_size = 12 + 36 + 8 + (2 < channels ? 24 : 0); // add the size of ALACChannelLayoutInfo for more than 2 channels m_out->write(std::string{"kuki"}); m_out->write_uint64_be(kuki_size); m_out->write_uint8('\0'); m_out->write_uint8('\0'); m_out->write_uint8('\0'); m_out->write_uint8('\14'); m_out->write(std::string{"frma"}); m_out->write(std::string{"alac"}); m_out->write_uint32_be(12 + sizeof(alac::codec_config_t)); // ALAC Specific Info size = 36 (12 + sizeof(ALAXSpecificConfig)) m_out->write(std::string{"alac"}); // ALAC Specific Info ID m_out->write_uint32_be(0L); // Version Flags m_out->write(m_priv); // audio specific config auto alo = caf::channel_layout_t(); if (2 < channels) { switch (channels) { case 3: alo.channel_layout_tag = caf::channel_layout_t::mpeg_3_0_b; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center; break; case 4: alo.channel_layout_tag = caf::channel_layout_t::mpeg_4_0_b; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::center_surround; break; case 5: alo.channel_layout_tag = caf::channel_layout_t::mpeg_5_0_d; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround; break; case 6: alo.channel_layout_tag = caf::channel_layout_t::mpeg_5_1_d; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround | caf::channel_layout_t::lfe_screen; break; case 7: alo.channel_layout_tag = caf::channel_layout_t::aac_6_1; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround | caf::channel_layout_t::center_surround | caf::channel_layout_t::lfe_screen; break; case 8: alo.channel_layout_tag = caf::channel_layout_t::mpeg_7_1_b; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_center | caf::channel_layout_t::right_center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround | caf::channel_layout_t::lfe_screen; break; } auto acli = caf::channel_layout_info_t(); put_uint32_be(&acli.channel_layout_info_size, 24); // = sizeof(ALACChannelLayoutInfo) put_uint32_be(&acli.channel_layout_info_id, FOURCC('c', 'h', 'a', 'n')); // = 'chan' put_uint32_be(&acli.channel_layout_tag, alo.channel_layout_tag); m_out->write(&acli, sizeof(acli)); } // Terminator atom m_out->write_uint32_be(8); // Channel Layout Info Size m_out->write_uint32_be(0); // Channel Layout Info ID if (2 < channels) { m_out->write(std::string{"chan"}); // 'chan' chunk immediately following the kuki m_out->write_uint64_be(12ULL); // = sizeof(ALACAudioChannelLayout) m_out->write_uint32_be(alo.channel_layout_tag); m_out->write_uint32_be(alo.channel_bitmap); m_out->write_uint32_be(alo.number_channel_descriptions); } m_free_chunk_offset = m_out->getFilePointer(); // remember the location of m_free_chunk_size = 16384; auto free_chunk = memory_c::alloc(m_free_chunk_size); memset(free_chunk->get_buffer(), 0, sizeof(m_free_chunk_size)); // the 'free' chunk m_out->write(std::string{"free"}); m_out->write_uint64_be(m_free_chunk_size); m_out->write(free_chunk); m_data_chunk_offset = m_out->getFilePointer(); m_out->write(std::string{"data"}); // Audio Data Chunk m_out->write_uint64_be(-1LL); // mChunkSize (= -1 if unknown) m_out->write_uint32_be(1); // mEditCount }
file_status_e avi_reader_c::read_video() { if (m_video_frames_read >= m_max_video_frames) return flush_packetizer(m_vptzr); memory_cptr chunk; int key = 0; int old_video_frames_read = m_video_frames_read; int size, num_read; int dropped_frames_here = 0; do { size = AVI_frame_size(m_avi, m_video_frames_read); chunk = memory_c::alloc(size); num_read = AVI_read_frame(m_avi, reinterpret_cast<char *>(chunk->get_buffer()), &key); ++m_video_frames_read; if (0 > num_read) { // Error reading the frame: abort m_video_frames_read = m_max_video_frames; return flush_packetizer(m_vptzr); } else if (0 == num_read) ++dropped_frames_here; } while ((0 == num_read) && (m_video_frames_read < m_max_video_frames)); if (0 == num_read) // This is only the case if the AVI contains dropped frames only. return flush_packetizer(m_vptzr); size_t i; for (i = m_video_frames_read; i < m_max_video_frames; ++i) { if (0 != AVI_frame_size(m_avi, i)) break; int dummy_key; AVI_read_frame(m_avi, nullptr, &dummy_key); ++dropped_frames_here; ++m_video_frames_read; } int64_t timestamp = static_cast<int64_t>(static_cast<int64_t>(old_video_frames_read) * 1000000000ll / m_fps); int64_t duration = static_cast<int64_t>(static_cast<int64_t>(dropped_frames_here + 1) * 1000000000ll / m_fps); m_dropped_video_frames += dropped_frames_here; // AVC with framed packets (without NALU start codes but with length fields) // or non-AVC video track? if (0 >= m_avc_nal_size_size) PTZR(m_vptzr)->process(new packet_t(chunk, timestamp, duration, key ? VFT_IFRAME : VFT_PFRAMEAUTOMATIC, VFT_NOBFRAME)); else { // AVC video track without NALU start codes. Re-frame with NALU start codes. int offset = 0; while ((offset + m_avc_nal_size_size) < num_read) { int nalu_size = get_uint_be(chunk->get_buffer() + offset, m_avc_nal_size_size); offset += m_avc_nal_size_size; if ((offset + nalu_size) > num_read) break; memory_cptr nalu = memory_c::alloc(4 + nalu_size); put_uint32_be(nalu->get_buffer(), NALU_START_CODE); memcpy(nalu->get_buffer() + 4, chunk->get_buffer() + offset, nalu_size); offset += nalu_size; PTZR(m_vptzr)->process(new packet_t(nalu, timestamp, duration, key ? VFT_IFRAME : VFT_PFRAMEAUTOMATIC, VFT_NOBFRAME)); } } m_bytes_processed += num_read; return m_video_frames_read >= m_max_video_frames ? flush_packetizer(m_vptzr) : FILE_STATUS_MOREDATA; }
dts_compressor_c::dts_compressor_c() { memory_cptr bytes = memory_c::alloc(4); put_uint32_be(bytes->get_buffer(), DTS_HEADER_MAGIC); set_bytes(bytes); }
dirac_compressor_c::dirac_compressor_c() { memory_cptr bytes = memory_c::alloc(4); put_uint32_be(bytes->get_buffer(), DIRAC_SYNC_WORD); set_bytes(bytes); }
size_t fourcc_c::write(unsigned char *mem, fourcc_c::byte_order_t byte_order) { put_uint32_be(mem, val(m_value, byte_order)); return 4; }