mkvextract: extract Big Endian PCM (A_PCM/INT/BIG) to WAV

This commit is contained in:
Moritz Bunkus 2016-03-07 19:02:41 +01:00
parent efcfabc983
commit 139bc3b788
6 changed files with 35 additions and 1 deletions

View File

@ -1,5 +1,9 @@
2016-03-07 Moritz Bunkus <moritz@bunkus.org>
* mkvextract: new feature: implemented the extraction of Big
Endian PCM (codec ID A_PCM/INT/BIG) to WAV files. The content will
be byte-swapped into Little Endian PCM in the process.
* mkvmerge: enhancement: Big Endian PCM tracks will now be
byte-swapped into Little Endian PCM, and the codec ID
A_PCM/INT/LIT will be used. This was done due to a lot of players

View File

@ -19,6 +19,7 @@
#include "common/codec.h"
#include "common/ebml.h"
#include "common/list_utils.h"
#include "common/mm_io_x.h"
#include "common/mm_write_buffer_io.h"
#include "common/strings/editing.h"
@ -142,7 +143,7 @@ xtr_base_c::create_extractor(const std::string &new_codec_id,
return new xtr_base_c(new_codec_id, new_tid, tspec, "MPEG-1 Audio Layer 2/3");
else if (new_codec_id == MKV_A_DTS)
return new xtr_base_c(new_codec_id, new_tid, tspec, "Digital Theater System (DTS)");
else if (new_codec_id == MKV_A_PCM)
else if (mtx::included_in(new_codec_id, MKV_A_PCM, MKV_A_PCM_BE))
return new xtr_wav_c(new_codec_id, new_tid, tspec);
else if (new_codec_id == MKV_A_FLAC)
return new xtr_flac_c(new_codec_id, new_tid, tspec);

View File

@ -16,8 +16,11 @@
#include <matroska/KaxBlock.h>
#include "avilib.h"
#include "common/bswap.h"
#include "common/codec.h"
#include "common/ebml.h"
#include "common/endian.h"
#include "common/list_utils.h"
#include "common/mm_io_x.h"
#include "common/mm_write_buffer_io.h"
#include "extract/xtr_wav.h"
@ -60,6 +63,11 @@ xtr_wav_c::create_file(xtr_base_c *master,
put_uint16_le(&m_wh.common.wBitsPerSample, bps);
m_out->write(&m_wh, sizeof(wave_header));
if ((m_codec_id == MKV_A_PCM_BE) && mtx::included_in(bps, 16, 32, 64))
m_byte_swapper = bps == 16 ? mtx::bswap_buffer_16
: bps == 32 ? mtx::bswap_buffer_32
: mtx::bswap_buffer_64;
}
void
@ -72,6 +80,15 @@ xtr_wav_c::finish_file() {
m_out->write(&m_wh, sizeof(wave_header));
}
void
xtr_wav_c::handle_frame(xtr_frame_t &f) {
if (m_byte_swapper)
m_byte_swapper(f.frame->get_buffer(), f.frame->get_buffer(), f.frame->get_size());
m_out->write(f.frame);
m_bytes_written += f.frame->get_size();
}
// ------------------------------------------------------------------------
xtr_wavpack4_c::xtr_wavpack4_c(const std::string &codec_id,

View File

@ -20,12 +20,14 @@
class xtr_wav_c: public xtr_base_c {
private:
wave_header m_wh;
std::function<void(unsigned char const *, unsigned char *, std::size_t)> m_byte_swapper;
public:
xtr_wav_c(const std::string &codec_id, int64_t tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *master, KaxTrackEntry &track) override;
virtual void finish_file() override;
virtual void handle_frame(xtr_frame_t &f) override;
virtual const char *get_container_name() override {
return "WAV";

View File

@ -381,3 +381,4 @@ T_532chapter_generation_when_appending:5680a0ca3f974d43ff7e4c7482812a4c-ea8f0f1e
T_533chapter_generation_interval:63486951fe0717eec1e93cb8fadaed92-5a57214bb210f51311edc6e8fca19f3e-cbbd43701884c34ae5d1efd9baf39a04+0e5962f224c28b3a7fc2a318fddd7ea9+74621b5528a14b9bee0aa6b8ac28693b+dfb83af32a6472c8e2d41238b89c7521+b60c9078501798a674db97c83fd99b14+e662cf60c4365aaeff7e6b088904739d+32c2cea8051c9f848e090aac1b761cb7+ok-c3b953881e1f7d35d58ab0bfe590d7ba:passed:20160301-194459:2.043516559
T_534chapter_generation_when_appending_audio_only:000e4bfced4fae128abbb741545768c8-39028cc1508e5a37f879b3a459f3dbd2-fb20e8f516702d6a0fb9299120e6b508+e66dbfdf351112c62aa65faccdce8ee1+c4dc3cd790ee8397d0a6bdca84091981+3d716d93d0178aeabc66111b4dc10d9a+4fe4b6a15803e0c8d400ce07b4a9d48e+8b5ccf0e1b9fcba119d40727b9b7e8e4+f3f355cb0549efabdd9954f4448fc48d+ok-e668981666602602e2ed5a1b8d47f6db:passed:20160302-130929:0.645667954
T_535chapter_generation_interval_audio_only:4231b50be18c4320584d7e18c611431d-7149e4b581f601145db038035aba3ec4-7b37e30bfede450fec2a5e7b1e982b35+bb66d81871625190fbd7b15b02f6ca57+1285f17cbdb1259606bd7174e993b3f1+c0877adb7bf88212aae2212ab819cf57+78fcd2002d1a48752c5a8e4730cc2158+b2a259375cb03683b7fe6ffe95a53e21+f3f355cb0549efabdd9954f4448fc48d+ok-8f16b1baaedec4b22df0f566b39a105e:passed:20160302-131002:0.64531153
T_536extract_big_endian_pcm:8e57291db3e924e9bb45acb306426a0a:passed:20160307-190156:0.015845204

View File

@ -0,0 +1,9 @@
#!/usr/bin/ruby -w
# T_536extract_big_endian_pcm
describe "mkvextract / extract Big Endian PCM"
test "extraction" do
extract "data/mkv/big-endian-pcm.mka", 0 => tmp
hash_tmp
end