int wav_ac3wav_demuxer_c::decode_buffer(int len) { if (len < 8) return -1; if (m_swap_bytes) { memcpy( m_buf[m_cur_buf ^ 1]->get_buffer(), m_buf[m_cur_buf]->get_buffer(), 8); swab((char *)m_buf[m_cur_buf]->get_buffer() + 8, (char *)m_buf[m_cur_buf ^ 1]->get_buffer() + 8, len - 8); m_cur_buf ^= 1; } unsigned char *base = m_buf[m_cur_buf]->get_buffer(); if ((get_uint16_le(&base[0]) != AC3WAV_SYNC_WORD1) || (get_uint16_le(&base[2]) != AC3WAV_SYNC_WORD2) || (0x01 != base[4])) return -1; int payload_len = get_uint16_le(&base[6]) / 8; if ((payload_len + 8) > len) return -1; if (!m_ac3header.decode_header(&base[8], payload_len)) return -1; return payload_len; }
void wav_reader_c::dump_headers() { mxinfo(boost::format("File '%1%' wave_header dump\n" " riff:\n" " id: %2%%3%%4%%5%\n" " len: %6%\n" " wave_id: %7%%8%%9%%10%\n" " common:\n" " wFormatTag: %|11$04x|\n" " wChannels: %12%\n" " dwSamplesPerSec: %13%\n" " dwAvgBytesPerSec: %14%\n" " wBlockAlign: %15%\n" " wBitsPerSample: %16%\n" " actual format_tag: %17%\n") % m_ti.m_fname % char(m_wheader.riff.id[0]) % char(m_wheader.riff.id[1]) % char(m_wheader.riff.id[2]) % char(m_wheader.riff.id[3]) % get_uint32_le(&m_wheader.riff.len) % char(m_wheader.riff.wave_id[0]) % char(m_wheader.riff.wave_id[1]) % char(m_wheader.riff.wave_id[2]) % char(m_wheader.riff.wave_id[3]) % get_uint16_le(&m_wheader.common.wFormatTag) % get_uint16_le(&m_wheader.common.wChannels) % get_uint32_le(&m_wheader.common.dwSamplesPerSec) % get_uint32_le(&m_wheader.common.dwAvgBytesPerSec) % get_uint16_le(&m_wheader.common.wBlockAlign) % get_uint16_le(&m_wheader.common.wBitsPerSample) % m_format_tag); }
void tta_reader_c::create_packetizer(int64_t) { if (!demuxing_requested('a', 0) || (NPTZR() != 0)) return; add_packetizer(new tta_packetizer_c(this, m_ti, get_uint16_le(&header.channels), get_uint16_le(&header.bits_per_sample), get_uint32_le(&header.sample_rate))); show_packetizer_info(0, PTZR0); }
wav_pcm_demuxer_c::wav_pcm_demuxer_c(wav_reader_c *reader, wave_header *wheader, bool _float): wav_demuxer_c(reader, wheader), m_bps(0), ieee_float(_float) { m_bps = get_uint16_le(&m_wheader->common.wChannels) * get_uint16_le(&m_wheader->common.wBitsPerSample) * get_uint32_le(&m_wheader->common.dwSamplesPerSec) / 8; m_buffer = memory_c::alloc(m_bps); }
generic_packetizer_c * wav_pcm_demuxer_c::create_packetizer() { m_ptzr = new pcm_packetizer_c(m_reader, m_ti, get_uint32_le(&m_wheader->common.dwSamplesPerSec), get_uint16_le(&m_wheader->common.wChannels), get_uint16_le(&m_wheader->common.wBitsPerSample), ieee_float ? pcm_packetizer_c::ieee_float : pcm_packetizer_c::little_endian_integer); show_packetizer_info(0, m_ptzr); return m_ptzr; }
void wav_reader_c::parse_file() { int chunk_idx; if (m_in->read(&m_wheader.riff, sizeof(m_wheader.riff)) != sizeof(m_wheader.riff)) throw mtx::input::header_parsing_x(); scan_chunks(); if ((chunk_idx = find_chunk("fmt ")) == -1) throw mtx::input::header_parsing_x(); m_in->setFilePointer(m_chunks[chunk_idx].pos, seek_beginning); try { if (m_in->read(&m_wheader.format, sizeof(m_wheader.format)) != sizeof(m_wheader.format)) throw false; if (static_cast<uint64_t>(m_chunks[chunk_idx].len) >= sizeof(alWAVEFORMATEXTENSIBLE)) { alWAVEFORMATEXTENSIBLE format; if (m_in->read(&format, sizeof(format)) != sizeof(format)) throw false; memcpy(&m_wheader.common, &format, sizeof(m_wheader.common)); m_format_tag = get_uint16_le(&m_wheader.common.wFormatTag); if (0xfffe == m_format_tag) m_format_tag = get_uint32_le(&format.extension.guid.data1); } else if (m_in->read(&m_wheader.common, sizeof(m_wheader.common)) != sizeof(m_wheader.common)) throw false; else m_format_tag = get_uint16_le(&m_wheader.common.wFormatTag); } catch (...) { throw mtx::input::header_parsing_x(); } if ((m_cur_data_chunk_idx = find_chunk("data", 0, false)) == -1) throw mtx::input::header_parsing_x(); if (debugging_c::requested("wav_reader|wav_reader_headers")) dump_headers(); m_in->setFilePointer(m_chunks[m_cur_data_chunk_idx].pos + sizeof(struct chunk_struct), seek_beginning); m_remaining_bytes_in_current_data_chunk = m_chunks[m_cur_data_chunk_idx].len; }
void avi_reader_c::identify_audio() { int i; for (i = 0; i < AVI_audio_tracks(m_avi); i++) { AVI_set_audio_track(m_avi, i); unsigned int audio_format = AVI_audio_format(m_avi); alWAVEFORMATEX *wfe = m_avi->wave_format_ex[i]; if ((0xfffe == audio_format) && (get_uint16_le(&wfe->cb_size) >= (sizeof(alWAVEFORMATEXTENSION)))) { alWAVEFORMATEXTENSIBLE *ext = reinterpret_cast<alWAVEFORMATEXTENSIBLE *>(wfe); audio_format = get_uint32_le(&ext->extension.guid.data1); } std::string type = (0x0001 == audio_format) || (0x0003 == audio_format) ? "PCM" : (0x0050 == audio_format) ? "MP2" : (0x0055 == audio_format) ? "MP3" : (0x2000 == audio_format) ? "AC3" : (0x2001 == audio_format) ? "DTS" : (0x0050 == audio_format) ? "MP2" : (0x00ff == audio_format) || (0x706d == audio_format) ? "AAC" : (0x566f == audio_format) ? "Vorbis" : (boost::format("unsupported (0x%|1$04x|)") % audio_format).str(); id_result_track(i + 1, ID_RESULT_TRACK_AUDIO, type); } }
void wav_reader_c::identify() { if (!m_demuxer) { uint16_t format_tag = get_uint16_le(&m_wheader.common.wFormatTag); id_result_container_unsupported(m_in->get_file_name(), (boost::format("RIFF WAVE (wFormatTag = 0x%|1$04x|)") % format_tag).str()); return; } std::vector<std::string> verbose_info; verbose_info.push_back((boost::format("channels:%1%") % get_uint16_le(&m_wheader.common.wChannels)).str()); verbose_info.push_back((boost::format("sample_rate:%1%") % get_uint32_le(&m_wheader.common.dwSamplesPerSec)).str()); verbose_info.push_back((boost::format("bits_per_sample:%1%") % get_uint16_le(&m_wheader.common.wBitsPerSample)).str()); id_result_container(); id_result_track(0, ID_RESULT_TRACK_AUDIO, m_demuxer->m_codec.get_name(), verbose_info); }
uint16_t mm_io_c::read_uint16_le() { unsigned char buffer[2]; if (read(buffer, 2) != 2) throw mtx::mm_io::end_of_file_x(); return get_uint16_le(buffer); }
void tta_reader_c::read_headers() { if (g_identifying) return; try { int tag_size = skip_id3v2_tag(*m_in); if (0 > tag_size) mxerror_fn(m_ti.m_fname, boost::format(Y("tta_reader: tag_size < 0 in the c'tor. %1%\n")) % BUGMSG); m_size -= tag_size; if (m_in->read(&header, sizeof(tta_file_header_t)) != sizeof(tta_file_header_t)) mxerror_fn(m_ti.m_fname, Y("The file header is too short.\n")); uint64_t seek_sum = m_in->getFilePointer() + 4 - tag_size; m_size -= id3_tag_present_at_end(*m_in); uint32_t seek_point; do { seek_point = m_in->read_uint32_le(); seek_sum += seek_point + 4; seek_points.push_back(seek_point); } while (seek_sum < m_size); mxverb(2, boost::format("tta: ch %1% bps %2% sr %3% dl %4% seek_sum %5% size %6% num %7%\n") % get_uint16_le(&header.channels) % get_uint16_le(&header.bits_per_sample) % get_uint32_le(&header.sample_rate) % get_uint32_le(&header.data_length) % seek_sum % m_size % seek_points.size()); if (seek_sum != m_size) mxerror_fn(m_ti.m_fname, Y("The seek table in this TTA file seems to be broken.\n")); m_in->skip(4); pos = 0; m_ti.m_id = 0; // ID for this track. } catch (...) { throw mtx::input::open_x(); } show_demuxer_info(); }
void ivf_reader_c::read_headers() { try { ivf::file_header_t header; m_in->read(&header, sizeof(ivf::file_header_t)); m_width = get_uint16_le(&header.width); m_height = get_uint16_le(&header.height); m_frame_rate_num = get_uint32_le(&header.frame_rate_num); m_frame_rate_den = get_uint32_le(&header.frame_rate_den); m_ti.m_id = 0; // ID for this track. } catch (...) { throw mtx::input::open_x(); } show_demuxer_info(); }
void wav_reader_c::identify() { if (m_demuxer) { id_result_container(); id_result_track(0, ID_RESULT_TRACK_AUDIO, m_demuxer->get_codec()); } else { uint16_t format_tag = get_uint16_le(&m_wheader.common.wFormatTag); id_result_container_unsupported(m_in->get_file_name(), (boost::format("RIFF WAVE (wFormatTag = 0x%|1$04x|)") % format_tag).str()); } }
void avi_reader_c::identify_audio() { int i; for (i = 0; i < AVI_audio_tracks(m_avi); i++) { AVI_set_audio_track(m_avi, i); auto info = mtx::id::info_c{}; info.add(mtx::id::audio_channels, AVI_audio_channels(m_avi)); info.add(mtx::id::audio_sampling_frequency, AVI_audio_rate(m_avi)); info.add(mtx::id::audio_bits_per_sample, AVI_audio_bits(m_avi)); unsigned int audio_format = AVI_audio_format(m_avi); alWAVEFORMATEX *wfe = m_avi->wave_format_ex[i]; if ((0xfffe == audio_format) && (get_uint16_le(&wfe->cb_size) >= (sizeof(alWAVEFORMATEXTENSION)))) { alWAVEFORMATEXTENSIBLE *ext = reinterpret_cast<alWAVEFORMATEXTENSIBLE *>(wfe); audio_format = get_uint32_le(&ext->extension.guid.data1); } auto codec = codec_c::look_up_audio_format(audio_format); id_result_track(i + 1, ID_RESULT_TRACK_AUDIO, codec.get_name((boost::format("unsupported (0x%|1$04x|)") % audio_format).str()), info.get()); } }
void avi_reader_c::add_audio_demuxer(int aid) { for (auto &demuxer : m_audio_demuxers) if (demuxer.m_aid == aid) // Demuxer already added? return; AVI_set_audio_track(m_avi, aid); if (AVI_read_audio_chunk(m_avi, nullptr) < 0) { mxwarn(boost::format(Y("Could not find an index for audio track %1% (avilib error message: %2%). Skipping track.\n")) % (aid + 1) % AVI_strerror()); return; } avi_demuxer_t demuxer; generic_packetizer_c *packetizer = nullptr; alWAVEFORMATEX *wfe = m_avi->wave_format_ex[aid]; uint32_t audio_format = AVI_audio_format(m_avi); demuxer.m_aid = aid; demuxer.m_ptzr = -1; demuxer.m_samples_per_second = AVI_audio_rate(m_avi); demuxer.m_channels = AVI_audio_channels(m_avi); demuxer.m_bits_per_sample = AVI_audio_bits(m_avi); m_ti.m_id = aid + 1; // ID for this audio track. m_ti.m_avi_block_align = get_uint16_le(&wfe->n_block_align); m_ti.m_avi_avg_bytes_per_sec = get_uint32_le(&wfe->n_avg_bytes_per_sec); m_ti.m_avi_samples_per_chunk = get_uint32_le(&m_avi->stream_headers[aid].dw_scale); m_ti.m_avi_sample_scale = get_uint32_le(&m_avi->stream_headers[aid].dw_rate); m_ti.m_avi_samples_per_sec = demuxer.m_samples_per_second; if ((0xfffe == audio_format) && (get_uint16_le(&wfe->cb_size) >= (sizeof(alWAVEFORMATEXTENSION)))) { alWAVEFORMATEXTENSIBLE *ext = reinterpret_cast<alWAVEFORMATEXTENSIBLE *>(wfe); audio_format = get_uint32_le(&ext->extension.guid.data1); } else if (get_uint16_le(&wfe->cb_size) > 0) m_ti.m_private_data = memory_c::clone(wfe + 1, get_uint16_le(&wfe->cb_size)); else m_ti.m_private_data.reset(); switch(audio_format) { case 0x0001: // raw PCM audio case 0x0003: // raw PCM audio (float) packetizer = new pcm_packetizer_c(this, m_ti, demuxer.m_samples_per_second, demuxer.m_channels, demuxer.m_bits_per_sample, 0x0003 == audio_format ? pcm_packetizer_c::ieee_float : pcm_packetizer_c::little_endian_integer); break; case 0x0050: // MP2 case 0x0055: // MP3 packetizer = new mp3_packetizer_c(this, m_ti, demuxer.m_samples_per_second, demuxer.m_channels, false); break; case 0x2000: // AC3 packetizer = new ac3_packetizer_c(this, m_ti, demuxer.m_samples_per_second, demuxer.m_channels, 0); break; case 0x2001: // DTS packetizer = create_dts_packetizer(aid); break; case 0x00ff: case 0x706d: // AAC packetizer = create_aac_packetizer(aid, demuxer); break; case 0x566f: // Vorbis packetizer = create_vorbis_packetizer(aid); break; default: mxerror_tid(m_ti.m_fname, aid + 1, boost::format(Y("Unknown/unsupported audio format 0x%|1$04x| for this audio track.\n")) % audio_format); } show_packetizer_info(aid + 1, packetizer); demuxer.m_ptzr = add_packetizer(packetizer); m_audio_demuxers.push_back(demuxer); int i, maxchunks = AVI_audio_chunks(m_avi); for (i = 0; i < maxchunks; i++) m_bytes_to_process += AVI_audio_size(m_avi, i); }
int16_t get_int16_le(uint8_t *buffer) { return((int16_t)get_uint16_le(buffer)); }
void avi_reader_c::add_audio_demuxer(int aid) { for (auto &demuxer : m_audio_demuxers) if (demuxer.m_aid == aid) // Demuxer already added? return; AVI_set_audio_track(m_avi, aid); if (AVI_read_audio_chunk(m_avi, nullptr) < 0) { mxwarn(boost::format(Y("Could not find an index for audio track %1% (avilib error message: %2%). Skipping track.\n")) % (aid + 1) % AVI_strerror()); return; } avi_demuxer_t demuxer; generic_packetizer_c *packetizer = nullptr; alWAVEFORMATEX *wfe = m_avi->wave_format_ex[aid]; uint32_t audio_format = AVI_audio_format(m_avi); demuxer.m_aid = aid; demuxer.m_ptzr = -1; demuxer.m_samples_per_second = AVI_audio_rate(m_avi); demuxer.m_channels = AVI_audio_channels(m_avi); demuxer.m_bits_per_sample = AVI_audio_bits(m_avi); m_ti.m_id = aid + 1; // ID for this audio track. auto stream_header = &m_avi->stream_headers[aid]; auto dw_scale = static_cast<int64_t>(get_uint32_le(&stream_header->dw_scale)); auto dw_rate = static_cast<int64_t>(get_uint32_le(&stream_header->dw_rate)); auto dw_sample_size = static_cast<int64_t>(get_uint32_le(&stream_header->dw_sample_size)); m_ti.m_avi_audio_data_rate = dw_scale ? dw_rate * dw_sample_size / dw_scale : 0; if ((0xfffe == audio_format) && (get_uint16_le(&wfe->cb_size) >= (sizeof(alWAVEFORMATEXTENSION)))) { alWAVEFORMATEXTENSIBLE *ext = reinterpret_cast<alWAVEFORMATEXTENSIBLE *>(wfe); audio_format = get_uint32_le(&ext->extension.guid.data1); } else if (get_uint16_le(&wfe->cb_size) > 0) m_ti.m_private_data = memory_c::clone(wfe + 1, get_uint16_le(&wfe->cb_size)); else m_ti.m_private_data.reset(); demuxer.m_codec = codec_c::look_up_audio_format(audio_format); if (demuxer.m_codec.is(codec_c::type_e::A_PCM)) packetizer = new pcm_packetizer_c(this, m_ti, demuxer.m_samples_per_second, demuxer.m_channels, demuxer.m_bits_per_sample, 0x0003 == audio_format ? pcm_packetizer_c::ieee_float : pcm_packetizer_c::little_endian_integer); else if (demuxer.m_codec.is(codec_c::type_e::A_MP2) || demuxer.m_codec.is(codec_c::type_e::A_MP3)) packetizer = new mp3_packetizer_c(this, m_ti, demuxer.m_samples_per_second, demuxer.m_channels, false); else if (demuxer.m_codec.is(codec_c::type_e::A_AC3)) packetizer = new ac3_packetizer_c(this, m_ti, demuxer.m_samples_per_second, demuxer.m_channels, 0); else if (demuxer.m_codec.is(codec_c::type_e::A_DTS)) packetizer = create_dts_packetizer(aid); else if (demuxer.m_codec.is(codec_c::type_e::A_AAC)) packetizer = create_aac_packetizer(aid, demuxer); else if (demuxer.m_codec.is(codec_c::type_e::A_VORBIS)) packetizer = create_vorbis_packetizer(aid); else mxerror_tid(m_ti.m_fname, aid + 1, boost::format(Y("Unknown/unsupported audio format 0x%|1$04x| for this audio track.\n")) % audio_format); packetizer->enable_avi_audio_sync(true); show_packetizer_info(aid + 1, packetizer); demuxer.m_ptzr = add_packetizer(packetizer); m_audio_demuxers.push_back(demuxer); int i, maxchunks = AVI_audio_chunks(m_avi); for (i = 0; i < maxchunks; i++) { auto size = AVI_audio_size(m_avi, i); if (size < AVI_MAX_AUDIO_CHUNK_SIZE) m_bytes_to_process += size; } }