mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-23 19:31:44 +00:00
Handling of block additions (for WAVPACK and other codecs). Patch by Steve Lhomme (see AUTHORS) with modifications by myself.
This commit is contained in:
parent
8e8d875f24
commit
bb865de9a1
@ -124,7 +124,7 @@ wv_parse_frame(mm_io_c *mm_io,
|
||||
meta.channel_count = (wphdr.flags & WV_MONO_FLAG) ? 1 : 2;
|
||||
total_bytes = wphdr.ck_size + 8;
|
||||
if (wphdr.flags & WV_FINAL_BLOCK) {
|
||||
mxverb(2, "wavpack_reader: %s block: %s, %d bytes\n",
|
||||
mxverb(3, "wavpack_reader: %s block: %s, %d bytes\n",
|
||||
(wphdr.flags & WV_MONO_FLAG) ? "mono" : "stereo",
|
||||
(wphdr.flags & WV_HYBRID_FLAG) ? "hybrid" : "lossless",
|
||||
wphdr.ck_size + 8);
|
||||
|
@ -45,12 +45,14 @@ typedef struct {
|
||||
char *out_name;
|
||||
|
||||
mm_io_c *out;
|
||||
mm_io_c *out2;
|
||||
avi_t *avi;
|
||||
ogg_stream_state osstate;
|
||||
rmff_track_t *rmtrack;
|
||||
|
||||
int64_t tid, tuid;
|
||||
bool in_use, done;
|
||||
int64_t max_blockadd_id;
|
||||
|
||||
char track_type;
|
||||
int type;
|
||||
|
@ -68,6 +68,7 @@ extern "C" {
|
||||
#include "chapters.h"
|
||||
#include "checksums.h"
|
||||
#include "common.h"
|
||||
#include "commonebml.h"
|
||||
#include "librmff.h"
|
||||
#include "matroska.h"
|
||||
#include "mkvextract.h"
|
||||
@ -361,12 +362,6 @@ check_output_files() {
|
||||
tracks[i].type = FILE_TYPE_TTA;
|
||||
|
||||
} else if (!strcmp(tracks[i].codec_id, MKV_A_WAVPACK4)) {
|
||||
if (tracks[i].private_data == NULL) {
|
||||
mxwarn(_("Track ID %lld is missing some critical "
|
||||
"information. The track will be skipped.\n"),
|
||||
tracks[i].tid);
|
||||
continue;
|
||||
}
|
||||
|
||||
tracks[i].type = FILE_TYPE_WAVPACK4;
|
||||
|
||||
@ -477,6 +472,27 @@ create_output_files() {
|
||||
dummy_out_name.c_str(), strerror(errno));
|
||||
}
|
||||
|
||||
} else if (tracks[i].type == FILE_TYPE_WAVPACK4) {
|
||||
|
||||
try {
|
||||
tracks[i].out = new mm_file_io_c(tracks[i].out_name, MODE_CREATE);
|
||||
if (tracks[i].max_blockadd_id != 0) {
|
||||
string tmpstr = tracks[i].out_name;
|
||||
size_t pos = tmpstr.rfind('.');
|
||||
if ((pos != string::npos) && (pos != 0))
|
||||
tmpstr = tmpstr.substr(0, pos - 1);
|
||||
tmpstr += "wvc";
|
||||
tracks[i].out2 = new mm_file_io_c(tmpstr, MODE_CREATE);
|
||||
}
|
||||
} catch (exception &ex) {
|
||||
mxerror(_(" The file '%s' could not be opened for writing (%s).\n"),
|
||||
tracks[i].out_name, strerror(errno));
|
||||
}
|
||||
|
||||
mxinfo(_("Track ID %lld is being extracted to a %s file '%s'.\n"),
|
||||
tracks[i].tid, typenames[tracks[i].type],
|
||||
tracks[i].out_name);
|
||||
|
||||
} else {
|
||||
|
||||
try {
|
||||
@ -643,6 +659,7 @@ create_output_files() {
|
||||
|
||||
static void
|
||||
handle_data(KaxBlock *block,
|
||||
KaxBlockAdditions *block_adds,
|
||||
int64_t block_duration,
|
||||
bool has_ref) {
|
||||
kax_track_t *track;
|
||||
@ -940,9 +957,27 @@ handle_data(KaxBlock *block,
|
||||
break;
|
||||
|
||||
case FILE_TYPE_WAVPACK4:
|
||||
// _todo_ support hybrid mode ?
|
||||
track->out->write("wvpk", 4);
|
||||
put_uint32_le(buffer, data.Size());
|
||||
track->out->write(buffer, 4);
|
||||
track->out->write(data.Buffer(), data.Size());
|
||||
track->bytes_written += data.Size();
|
||||
// support hybrid mode data
|
||||
if (track->out2 && block_adds) {
|
||||
KaxBlockMore *block_more = FINDFIRST(block_adds, KaxBlockMore);
|
||||
if (block_more == NULL)
|
||||
break;
|
||||
KaxBlockAdditional *block_addition =
|
||||
FINDFIRST(block_more, KaxBlockAdditional);
|
||||
if (block_addition == NULL)
|
||||
break;
|
||||
|
||||
track->out2->write("wvpk", 4);
|
||||
put_uint32_le(buffer, block_addition->GetSize() + 20);
|
||||
track->out2->write(buffer, 4);
|
||||
track->out2->write(data.Buffer(), 20);
|
||||
track->out2->write(block_addition->GetBuffer(),
|
||||
block_addition->GetSize());
|
||||
}
|
||||
break;
|
||||
|
||||
case FILE_TYPE_TTA:
|
||||
@ -1119,6 +1154,7 @@ close_files() {
|
||||
|
||||
default:
|
||||
delete tracks[i].out;
|
||||
delete tracks[i].out2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1297,7 +1333,7 @@ extract_tracks(const char *file_name) {
|
||||
if (EbmlId(*l2) == KaxTrackEntry::ClassInfos.GlobalId) {
|
||||
int64_t tuid, default_duration;
|
||||
float a_sfreq, v_fps;
|
||||
int a_channels, a_bps, v_width, v_height;
|
||||
int a_channels, a_bps, v_width, v_height, max_blockadd_id;
|
||||
char kax_track_type, *codec_id;
|
||||
unsigned char *private_data;
|
||||
int private_size;
|
||||
@ -1319,6 +1355,7 @@ extract_tracks(const char *file_name) {
|
||||
private_data = NULL;
|
||||
private_size = 0;
|
||||
default_duration = 0;
|
||||
max_blockadd_id = 0;
|
||||
|
||||
upper_lvl_el = 0;
|
||||
l3 = es->FindNextElement(l2->Generic().Context, upper_lvl_el,
|
||||
@ -1340,6 +1377,13 @@ extract_tracks(const char *file_name) {
|
||||
show_element(l3, 3, _("Track number: %u (%s)"), uint32(tnum),
|
||||
msg);
|
||||
|
||||
} else if (is_id(l3, KaxMaxBlockAdditionID)) {
|
||||
KaxMaxBlockAdditionID &max_badd_id =
|
||||
*static_cast<KaxMaxBlockAdditionID *>(l3);
|
||||
max_badd_id.ReadData(es->I_O());
|
||||
max_blockadd_id = uint64(max_badd_id);
|
||||
show_element(l3, 3, _("Max BlockAdd ID: %u"), max_blockadd_id);
|
||||
|
||||
} else if (EbmlId(*l3) == KaxTrackUID::ClassInfos.GlobalId) {
|
||||
KaxTrackUID &el_tuid = *static_cast<KaxTrackUID *>(l3);
|
||||
el_tuid.ReadData(es->I_O());
|
||||
@ -1611,6 +1655,9 @@ extract_tracks(const char *file_name) {
|
||||
create_output_files();
|
||||
|
||||
} else if (EbmlId(*l1) == KaxCluster::ClassInfos.GlobalId) {
|
||||
KaxBlockAdditions *blockadds;
|
||||
|
||||
blockadds = NULL;
|
||||
show_element(l1, 1, _("Cluster"));
|
||||
cluster = (KaxCluster *)l1;
|
||||
|
||||
@ -1670,6 +1717,14 @@ extract_tracks(const char *file_name) {
|
||||
((float)int64(reference)) * tc_scale / 1000000.0);
|
||||
|
||||
has_reference = true;
|
||||
|
||||
} else if (EbmlId(*l3) ==
|
||||
KaxBlockAdditions::ClassInfos.GlobalId) {
|
||||
blockadds = static_cast<KaxBlockAdditions *>(l3);
|
||||
blockadds->ReadData(es->I_O(), SCOPE_ALL_DATA);
|
||||
show_element(l3, 3, _("Block Additions"));
|
||||
|
||||
has_reference = true;
|
||||
} else
|
||||
l3->SkipData(*es, l3->Generic().Context);
|
||||
|
||||
@ -1696,7 +1751,7 @@ extract_tracks(const char *file_name) {
|
||||
|
||||
// Now write the stuff to the file. Or not. Or get something to
|
||||
// drink. Or read a good book. Dunno, your choice, really.
|
||||
handle_data(block, block_duration, has_reference);
|
||||
handle_data(block, blockadds, block_duration, has_reference);
|
||||
|
||||
} else
|
||||
l2->SkipData(*es, l2->Generic().Context);
|
||||
|
@ -1093,6 +1093,12 @@ def_handle(tracks) {
|
||||
*static_cast<KaxTrackTimecodeScale *>(l3);
|
||||
show_element(l3, 3, "Timecode scale: %f", float(ttc_scale));
|
||||
|
||||
} else if (is_id(l3, KaxMaxBlockAdditionID)) {
|
||||
KaxMaxBlockAdditionID &max_block_add_id =
|
||||
*static_cast<KaxMaxBlockAdditionID *>(l3);
|
||||
show_element(l3, 3, "Max BlockAddition ID: %u",
|
||||
uint32(max_block_add_id));
|
||||
|
||||
} else if (is_id(l3, KaxContentEncodings))
|
||||
handle(content_encodings);
|
||||
|
||||
@ -1462,6 +1468,7 @@ def_handle2(block_group,
|
||||
show_element(l3, 3, "Reference virtual: %lld",
|
||||
int64(ref_virt));
|
||||
|
||||
#endif // MATROSKA_VERSION >= 2
|
||||
} else if (is_id(l3, KaxBlockAdditions)) {
|
||||
show_element(l3, 3, "Additions");
|
||||
|
||||
@ -1500,7 +1507,6 @@ def_handle2(block_group,
|
||||
show_unknown_element(l4, 4);
|
||||
|
||||
} // while (l4 != NULL)
|
||||
#endif // MATROSKA_VERSION >= 2
|
||||
|
||||
} else if (is_id(l3, KaxSlices)) {
|
||||
show_element(l3, 3, "Slices");
|
||||
|
@ -1747,11 +1747,11 @@ kax_reader_c::create_packetizer(int64_t tid) {
|
||||
(int64_t)t->tnum);
|
||||
|
||||
} else if (t->a_formattag == FOURCC('W', 'V', 'P', '4')) {
|
||||
/* _todo_:
|
||||
safefree(nti->private_data);
|
||||
nti->private_data = NULL;
|
||||
nti->private_size = 0;*/
|
||||
wavpack_meta_t meta;
|
||||
|
||||
safefree(nti->private_data);
|
||||
nti->private_data = NULL;
|
||||
nti->private_size = 0;
|
||||
meta.bits_per_sample = t->a_bps;
|
||||
meta.channel_count = t->a_channels;
|
||||
meta.sample_rate = (uint32_t)t->a_sfreq;
|
||||
|
@ -77,8 +77,8 @@ wavpack_reader_c::wavpack_reader_c(track_info_c *nti)
|
||||
if (packet_size < 0)
|
||||
mxerror(FMT_FN "The correction file header was not read correctly.\n",
|
||||
ti->fname.c_str());
|
||||
mm_io_correc->setFilePointer(-sizeof(wavpack_header_t),
|
||||
seek_current);
|
||||
mm_io_correc->setFilePointer(mm_io->getFilePointer() -
|
||||
sizeof(wavpack_header_t), seek_beginning);
|
||||
meta.has_correction = true;
|
||||
}
|
||||
} catch (exception &ex) {
|
||||
@ -88,7 +88,8 @@ wavpack_reader_c::wavpack_reader_c(track_info_c *nti)
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
mxinfo(FMT_FN "Using the WAVPACK demultiplexer.\n", ti->fname.c_str());
|
||||
mxinfo(FMT_FN "Using the WAVPACK demultiplexer%s.\n", ti->fname.c_str(),
|
||||
meta.has_correction ? " with a correction file" : "");
|
||||
}
|
||||
|
||||
wavpack_reader_c::~wavpack_reader_c() {
|
||||
@ -109,7 +110,7 @@ wavpack_reader_c::create_packetizer(int64_t) {
|
||||
file_status_e
|
||||
wavpack_reader_c::read(generic_packetizer_c *ptzr,
|
||||
bool force) {
|
||||
wavpack_header_t dummy_header;
|
||||
wavpack_header_t dummy_header, dummy_header_correc;
|
||||
wavpack_meta_t dummy_meta;
|
||||
int32_t data_size = wv_parse_frame(mm_io, dummy_header, dummy_meta);
|
||||
|
||||
@ -135,7 +136,45 @@ wavpack_reader_c::read(generic_packetizer_c *ptzr,
|
||||
|
||||
memory_c mem(chunk, data_size + sizeof(wavpack_header_t) -
|
||||
WV_KEEP_HEADER_POSITION, true);
|
||||
PTZR0->process(mem);
|
||||
|
||||
// find the if there is a correction file data corresponding
|
||||
memories_c mems;
|
||||
mems.push_back(&mem);
|
||||
|
||||
if (mm_io_correc) {
|
||||
do {
|
||||
data_size = wv_parse_frame(mm_io_correc, dummy_header_correc,
|
||||
dummy_meta);
|
||||
// no more correction to be found
|
||||
if (data_size < 0) {
|
||||
delete mm_io_correc;
|
||||
mm_io_correc = NULL;
|
||||
dummy_header_correc.block_samples = dummy_header.block_samples + 1;
|
||||
break;
|
||||
}
|
||||
} while (dummy_header_correc.block_samples < dummy_header.block_samples);
|
||||
|
||||
if (dummy_header_correc.block_samples == dummy_header.block_samples) {
|
||||
|
||||
uint8_t *chunk_correc = (uint8_t *)safemalloc(data_size + 4);
|
||||
|
||||
// only keep the CRC in the header
|
||||
put_uint32_le(chunk_correc, dummy_header_correc.crc);
|
||||
|
||||
if (mm_io_correc->read(&chunk_correc[4], data_size) < 0) {
|
||||
delete mm_io_correc;
|
||||
mm_io_correc = NULL;
|
||||
}
|
||||
else {
|
||||
memory_c mem_correc(chunk_correc, data_size + 4, true);
|
||||
mems.push_back(&mem_correc);
|
||||
PTZR0->process(mems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mems.size() == 1)
|
||||
PTZR0->process(mem);
|
||||
|
||||
return FILE_STATUS_MOREDATA;
|
||||
}
|
||||
|
@ -69,18 +69,14 @@ cluster_helper_c::~cluster_helper_c() {
|
||||
|
||||
void
|
||||
cluster_helper_c::free_contents(ch_contents_t *clstr) {
|
||||
packet_t *p;
|
||||
int i;
|
||||
vector<packet_t *>::iterator i;
|
||||
|
||||
assert(clstr != NULL);
|
||||
assert(clstr->cluster != NULL);
|
||||
delete clstr->cluster;
|
||||
|
||||
for (i = 0; i < clstr->packets.size(); i++) {
|
||||
p = clstr->packets[i];
|
||||
safefree(p->data);
|
||||
safefree(p);
|
||||
}
|
||||
foreach(i, clstr->packets)
|
||||
delete *i;
|
||||
delete clstr;
|
||||
}
|
||||
|
||||
@ -504,6 +500,23 @@ cluster_helper_c::render_cluster(ch_contents_t *clstr) {
|
||||
(&GetChild<KaxReferencePriority>(*new_block_group)) =
|
||||
pack->ref_priority;
|
||||
|
||||
// Handle BlockAdditions if needed
|
||||
if ((new_block_group != NULL) && (pack->data_adds.size() > 0)) {
|
||||
KaxBlockAdditions *additions = static_cast<KaxBlockAdditions *>
|
||||
(&GetChild<KaxBlockAdditions>(*new_block_group));
|
||||
for (k = 0; k < pack->data_adds.size(); k++) {
|
||||
KaxBlockMore *block_more = static_cast<KaxBlockMore *>
|
||||
(&GetChild<KaxBlockMore>(*additions));
|
||||
*static_cast<EbmlUInteger *>(&GetChild<KaxBlockAddID>(*block_more)) =
|
||||
k + 1;
|
||||
KaxBlockAdditional *block_additional =
|
||||
static_cast<KaxBlockAdditional *>
|
||||
(&GetChild<KaxBlockAdditional>(*block_more));
|
||||
block_additional->SetBuffer((binary *)pack->data_adds[k],
|
||||
pack->data_adds_lengths[k]);
|
||||
}
|
||||
}
|
||||
|
||||
elements_in_cluster++;
|
||||
|
||||
if (new_block_group == NULL)
|
||||
|
@ -806,8 +806,7 @@ generic_packetizer_c::add_packet(memory_c &mem,
|
||||
if (reader->ptzr_first_packet == NULL)
|
||||
reader->ptzr_first_packet = this;
|
||||
|
||||
pack = (packet_t *)safemalloc(sizeof(packet_t));
|
||||
memset(pack, 0, sizeof(packet_t));
|
||||
pack = new packet_t;
|
||||
|
||||
length = mem.size;
|
||||
if (compressor != NULL) {
|
||||
@ -836,6 +835,73 @@ generic_packetizer_c::add_packet(memory_c &mem,
|
||||
deferred_packets.push_back(pack);
|
||||
}
|
||||
|
||||
void
|
||||
generic_packetizer_c::add_packet(memories_c &mems,
|
||||
int64_t timecode,
|
||||
int64_t duration,
|
||||
bool duration_mandatory,
|
||||
int64_t bref,
|
||||
int64_t fref,
|
||||
int ref_priority) {
|
||||
int length, add_length, i;
|
||||
packet_t *pack;
|
||||
|
||||
if (reader->ptzr_first_packet == NULL)
|
||||
reader->ptzr_first_packet = this;
|
||||
|
||||
pack = (packet_t *)safemalloc(sizeof(packet_t));
|
||||
memset(pack, 0, sizeof(packet_t));
|
||||
pack->data_adds.clear();
|
||||
pack->data_adds.resize(mems.size() - 1);
|
||||
|
||||
length = mems[0]->size;
|
||||
if (compressor != NULL) {
|
||||
pack->data = compressor->compress(mems[0]->data, length);
|
||||
mems[0]->release();
|
||||
for (i = 1; i < mems.size(); i++) {
|
||||
add_length = mems[i]->size;
|
||||
pack->data_adds.push_back(compressor->compress(mems[i]->data,
|
||||
add_length));
|
||||
pack->data_adds_lengths.push_back(add_length);
|
||||
mems[i]->release();
|
||||
}
|
||||
} else {
|
||||
if (!mems[0]->is_free)
|
||||
pack->data = (unsigned char *)safememdup(mems[0]->data, length);
|
||||
else {
|
||||
pack->data = mems[0]->data;
|
||||
mems[0]->lock();
|
||||
}
|
||||
for (i = 1; i < mems.size(); i++) {
|
||||
if (!mems[i]->is_free) {
|
||||
add_length = mems[i]->size;
|
||||
pack->data_adds.push_back((unsigned char *)safememdup(mems[i]->data,
|
||||
add_length));
|
||||
pack->data_adds_lengths.push_back(add_length);
|
||||
} else {
|
||||
pack->data_adds.push_back(mems[i]->data);
|
||||
pack->data_adds_lengths.push_back(mems[i]->size);
|
||||
mems[i]->lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
pack->length = length;
|
||||
pack->timecode = timecode;
|
||||
pack->bref = bref;
|
||||
pack->fref = fref;
|
||||
pack->ref_priority = ref_priority;
|
||||
pack->duration = duration;
|
||||
pack->duration_mandatory = duration_mandatory;
|
||||
pack->source = this;
|
||||
|
||||
enqueued_bytes += pack->length;
|
||||
|
||||
if (connected_to != 1)
|
||||
add_packet2(pack);
|
||||
else
|
||||
deferred_packets.push_back(pack);
|
||||
}
|
||||
|
||||
void
|
||||
generic_packetizer_c::add_packet2(packet_t *pack) {
|
||||
int64_t factory_timecode;
|
||||
@ -847,8 +913,7 @@ generic_packetizer_c::add_packet2(packet_t *pack) {
|
||||
pack->fref += correction_timecode_offset + append_timecode_offset;
|
||||
|
||||
if (pack->timecode < 0) {
|
||||
safefree(pack->data);
|
||||
safefree(pack);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<memory_c *> memories_c;
|
||||
|
||||
struct audio_sync_t {
|
||||
int64_t displacement;
|
||||
double linear;
|
||||
@ -132,7 +134,7 @@ enum default_track_priority_e {
|
||||
#define FMT_FN "'%s': "
|
||||
#define FMT_TID "'%s' track %lld: "
|
||||
|
||||
typedef struct {
|
||||
struct packet_t {
|
||||
KaxBlockGroup *group;
|
||||
KaxBlock *block;
|
||||
KaxCluster *cluster;
|
||||
@ -142,7 +144,27 @@ typedef struct {
|
||||
int64_t unmodified_assigned_timecode, unmodified_duration;
|
||||
bool duration_mandatory, superseeded, gap_following;
|
||||
generic_packetizer_c *source;
|
||||
} packet_t;
|
||||
vector<unsigned char *> data_adds;
|
||||
vector<int> data_adds_lengths;
|
||||
|
||||
packet_t():
|
||||
group(NULL), block(NULL), cluster(NULL), data(NULL), length(0),
|
||||
ref_priority(0),
|
||||
timecode(0), bref(0), fref(0), duration(0),
|
||||
packet_num(0),
|
||||
assigned_timecode(0), unmodified_assigned_timecode(0),
|
||||
unmodified_duration(0),
|
||||
duration_mandatory(false), superseeded(false), gap_following(false),
|
||||
source(NULL) {}
|
||||
|
||||
virtual ~packet_t() {
|
||||
vector<unsigned char *>::iterator i;
|
||||
|
||||
safefree(data);
|
||||
foreach(i, data_adds)
|
||||
safefree(*i);
|
||||
}
|
||||
};
|
||||
|
||||
struct cue_creation_t {
|
||||
cue_strategy_e cues;
|
||||
@ -433,6 +455,10 @@ public:
|
||||
int64_t duration, bool duration_mandatory = false,
|
||||
int64_t bref = -1, int64_t fref = -1,
|
||||
int ref_priority = -1);
|
||||
virtual void add_packet(memories_c &mems, int64_t timecode,
|
||||
int64_t duration, bool duration_mandatory = false,
|
||||
int64_t bref = -1, int64_t fref = -1,
|
||||
int ref_priority = -1);
|
||||
virtual void add_packet2(packet_t *pack);
|
||||
virtual void process_deferred_packets();
|
||||
|
||||
@ -462,6 +488,12 @@ public:
|
||||
int64_t timecode = -1, int64_t length = -1,
|
||||
int64_t bref = -1, int64_t fref = -1) = 0;
|
||||
|
||||
virtual int process(memories_c &mems,
|
||||
int64_t timecode = -1, int64_t length = -1,
|
||||
int64_t bref = -1, int64_t fref = -1) {
|
||||
return process(*mems[0], timecode, length, bref, fref);
|
||||
}
|
||||
|
||||
virtual void dump_debug_info() = 0;
|
||||
|
||||
virtual void set_cue_creation(cue_strategy_e create_cue_data) {
|
||||
|
@ -47,9 +47,10 @@ wavpack_packetizer_c::set_headers() {
|
||||
set_audio_bit_depth(bits_per_sample);
|
||||
set_track_default_duration(samples_per_block * 1000000000 / sample_rate);
|
||||
set_track_max_additionals(has_correction ? 1 : 0);
|
||||
// _todo_ specify in the track header if it's using BlockAdditionals
|
||||
|
||||
generic_packetizer_c::set_headers();
|
||||
|
||||
track_entry->EnableLacing(!has_correction);
|
||||
}
|
||||
|
||||
int
|
||||
@ -78,6 +79,34 @@ wavpack_packetizer_c::process(memory_c &mem,
|
||||
return FILE_STATUS_MOREDATA;
|
||||
}
|
||||
|
||||
int
|
||||
wavpack_packetizer_c::process(memories_c &mems,
|
||||
int64_t,
|
||||
int64_t duration,
|
||||
int64_t,
|
||||
int64_t) {
|
||||
debug_enter("wavpack_packetizer_c::process");
|
||||
memory_c & mem = *mems[0];
|
||||
// memory_c & mem_correc = *mems[1];
|
||||
int64_t samples = get_uint32_le(&mem.data[12]);
|
||||
int64_t sample_index = get_uint32_le(&mem.data[8]);
|
||||
|
||||
if (duration == -1) {
|
||||
add_packet(mems, irnd(sample_index * 1000000000 / sample_rate),
|
||||
irnd(samples * 1000000000 / sample_rate));
|
||||
} else {
|
||||
mxverb(2, "wavpack_packetizer: incomplete block with duration %lld\n",
|
||||
duration);
|
||||
add_packet(mems, irnd((double)sample_index * 1000000000 / sample_rate),
|
||||
duration);
|
||||
}
|
||||
samples_output = sample_index + samples;
|
||||
|
||||
debug_leave("wavpack_packetizer_c::process");
|
||||
|
||||
return FILE_STATUS_MOREDATA;
|
||||
}
|
||||
|
||||
void
|
||||
wavpack_packetizer_c::dump_debug_info() {
|
||||
mxdebug("wavpack_packetizer_c: queue: %d\n", packet_queue.size());
|
||||
|
@ -37,6 +37,9 @@ public:
|
||||
virtual int process(memory_c &mem, int64_t timecode = -1,
|
||||
int64_t length = -1, int64_t bref = -1,
|
||||
int64_t fref = -1);
|
||||
virtual int process(memories_c &mem,
|
||||
int64_t timecode = -1, int64_t length = -1,
|
||||
int64_t bref = -1, int64_t fref = -1);
|
||||
virtual void set_headers();
|
||||
|
||||
virtual void dump_debug_info();
|
||||
|
Loading…
Reference in New Issue
Block a user