From 4987608d83328ae1e5ce1bdda5873773056fefc0 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 19 Oct 2005 16:52:55 +0000 Subject: [PATCH] Changed all extractors' handle_block() function to take a memory_cptr for the memory buffer, a couple of boolean flags and only handle one frame each (and not a complete block group). This is a preparation for easier simpleblock support. --- src/extract/tracks.cpp | 4 +- src/extract/xtr_aac.cpp | 89 +++++++++--------- src/extract/xtr_aac.h | 5 +- src/extract/xtr_avc.cpp | 19 ++-- src/extract/xtr_avc.h | 5 +- src/extract/xtr_avi.cpp | 29 +++--- src/extract/xtr_avi.h | 5 +- src/extract/xtr_base.cpp | 49 ++++++++-- src/extract/xtr_base.h | 8 +- src/extract/xtr_ogg.cpp | 54 +++++------ src/extract/xtr_ogg.h | 8 +- src/extract/xtr_rmff.cpp | 40 ++++----- src/extract/xtr_rmff.h | 5 +- src/extract/xtr_textsubs.cpp | 46 +++++----- src/extract/xtr_textsubs.h | 15 ++-- src/extract/xtr_tta.cpp | 17 ++-- src/extract/xtr_tta.h | 5 +- src/extract/xtr_vobsub.cpp | 170 +++++++++++++++++------------------ src/extract/xtr_vobsub.h | 5 +- src/extract/xtr_wav.cpp | 147 +++++++++++++++--------------- src/extract/xtr_wav.h | 5 +- 21 files changed, 377 insertions(+), 353 deletions(-) diff --git a/src/extract/tracks.cpp b/src/extract/tracks.cpp index 1d971c224..79a7c1bff 100644 --- a/src/extract/tracks.cpp +++ b/src/extract/tracks.cpp @@ -195,8 +195,8 @@ handle_blockgroup(KaxBlockGroup &blockgroup, kadditions = FINDFIRST(&blockgroup, KaxBlockAdditions); // Pass the block to the extractor. - extractor->handle_block(*block, kadditions, block->GlobalTimecode(), - duration, bref, fref); + extractor->handle_block_v1(*block, kadditions, block->GlobalTimecode(), + duration, bref, fref); } static void diff --git a/src/extract/xtr_aac.cpp b/src/extract/xtr_aac.cpp index 051fce5e8..e2fafe2c5 100644 --- a/src/extract/xtr_aac.cpp +++ b/src/extract/xtr_aac.cpp @@ -82,70 +82,69 @@ xtr_aac_c::create_file(xtr_base_c *_master, } void -xtr_aac_c::handle_block(KaxBlock &block, +xtr_aac_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { char adts[56 / 8]; - int i, len; + int len; - for (i = 0; i < block.NumberFrames(); i++) { - DataBuffer &data = block.GetBuffer(i); + // Recreate the ADTS headers. What a fun. Like runing headlong into + // a solid wall. But less painful. Well such is life, you know. + // But then again I've just seen a beautiful girl walking by my + // window, and suddenly the world is a bright place. Everything's + // a matter of perspective. And if I didn't enjoy writing even this + // code then I wouldn't do it at all. So let's get to it! - // Recreate the ADTS headers. What a fun. Like runing headlong into - // a solid wall. But less painful. Well such is life, you know. - // But then again I've just seen a beautiful girl walking by my - // window, and suddenly the world is a bright place. Everything's - // a matter of perspective. And if I didn't enjoy writing even this - // code then I wouldn't do it at all. So let's get to it! + // sync word, 12 bits + adts[0] = 0xff; + adts[1] = 0xf0; - // sync word, 12 bits - adts[0] = 0xff; - adts[1] = 0xf0; + // ID, 1 bit + adts[1] |= id << 3; + // layer: 2 bits = 00 - // ID, 1 bit - adts[1] |= id << 3; - // layer: 2 bits = 00 + // protection absent: 1 bit = 1 (ASSUMPTION!) + adts[1] |= 1; - // protection absent: 1 bit = 1 (ASSUMPTION!) - adts[1] |= 1; + // profile, 2 bits + adts[2] = profile << 6; - // profile, 2 bits - adts[2] = profile << 6; + // sampling frequency index, 4 bits + adts[2] |= srate_idx << 2; - // sampling frequency index, 4 bits - adts[2] |= srate_idx << 2; + // private, 1 bit = 0 (ASSUMPTION!) - // private, 1 bit = 0 (ASSUMPTION!) + // channels, 3 bits + adts[2] |= (channels & 4) >> 2; + adts[3] = (channels & 3) << 6; - // channels, 3 bits - adts[2] |= (channels & 4) >> 2; - adts[3] = (channels & 3) << 6; + // original/copy, 1 bit = 0(ASSUMPTION!) - // original/copy, 1 bit = 0(ASSUMPTION!) + // home, 1 bit = 0 (ASSUMPTION!) - // home, 1 bit = 0 (ASSUMPTION!) + // copyright id bit, 1 bit = 0 (ASSUMPTION!) - // copyright id bit, 1 bit = 0 (ASSUMPTION!) + // copyright id start, 1 bit = 0 (ASSUMPTION!) - // copyright id start, 1 bit = 0 (ASSUMPTION!) + // frame length, 13 bits + len = frame->get_size() + 7; + adts[3] |= len >> 11; + adts[4] = (len >> 3) & 0xff; + adts[5] = (len & 7) << 5; - // frame length, 13 bits - len = data.Size() + 7; - adts[3] |= len >> 11; - adts[4] = (len >> 3) & 0xff; - adts[5] = (len & 7) << 5; + // adts buffer fullness, 11 bits, 0x7ff = VBR (ASSUMPTION!) + adts[5] |= 0x1f; + adts[6] = 0xfc; - // adts buffer fullness, 11 bits, 0x7ff = VBR (ASSUMPTION!) - adts[5] |= 0x1f; - adts[6] = 0xfc; + // number of raw frames, 2 bits, 0 (meaning 1 frame) (ASSUMPTION!) - // number of raw frames, 2 bits, 0 (meaning 1 frame) (ASSUMPTION!) - - // Write the ADTS header and the data itself. - out->write(adts, 56 / 8); - out->write(data.Buffer(), data.Size()); - } + // Write the ADTS header and the data itself. + out->write(adts, 56 / 8); + out->write(frame->get(), frame->get_size()); } diff --git a/src/extract/xtr_aac.h b/src/extract/xtr_aac.h index db2d0e49c..474161504 100644 --- a/src/extract/xtr_aac.h +++ b/src/extract/xtr_aac.h @@ -27,9 +27,10 @@ public: xtr_aac_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); }; #endif diff --git a/src/extract/xtr_avc.cpp b/src/extract/xtr_avc.cpp index 5c89cae64..f4144d3e8 100644 --- a/src/extract/xtr_avc.cpp +++ b/src/extract/xtr_avc.cpp @@ -77,18 +77,19 @@ xtr_avc_c::create_file(xtr_base_c *_master, } void -xtr_avc_c::handle_block(KaxBlock &block, +xtr_avc_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { - int i, pos; + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { + int pos; + binary *buf = (binary *)frame->get(); - for (i = pos = 0; block.NumberFrames() > i; i++) { - DataBuffer &data = block.GetBuffer(i); - binary *buf = data.Buffer(); - while (data.Size() > pos) - write_nal(buf, pos, data.Size(), nal_size_size); - } + pos = 0; + while (frame->get_size() > pos) + write_nal(buf, pos, frame->get_size(), nal_size_size); } diff --git a/src/extract/xtr_avc.h b/src/extract/xtr_avc.h index caa9c1baf..8e85227b9 100644 --- a/src/extract/xtr_avc.h +++ b/src/extract/xtr_avc.h @@ -27,9 +27,10 @@ public: xtr_avc_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); void write_nal(const binary *data, int &pos, int data_size, int nal_size_size); }; diff --git a/src/extract/xtr_avi.cpp b/src/extract/xtr_avi.cpp index d68b32d20..6eff1f554 100644 --- a/src/extract/xtr_avi.cpp +++ b/src/extract/xtr_avi.cpp @@ -73,29 +73,26 @@ xtr_avi_c::create_file(xtr_base_c *_master, } void -xtr_avi_c::handle_block(KaxBlock &block, +xtr_avi_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { - int i; + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { + if (references_valid) + keyframe = bref == 0; - if (0 >= duration) - duration = default_duration; + AVI_write_frame(avi, (char *)frame->get(), frame->get_size(), keyframe); - for (i = 0; i < block.NumberFrames(); i++) { - DataBuffer &data = block.GetBuffer(i); + if (((double)duration / 1000000.0 - (1000.0 / fps)) >= 1.5) { + int k, nfr; - AVI_write_frame(avi, (char *)data.Buffer(), data.Size(), - bref != 0 ? 0 : 1); - if (((double)duration / 1000000.0 - (1000.0 / fps)) >= 1.5) { - int k, nfr; - - nfr = irnd((double)duration / 1000000.0 * fps / 1000.0); - for (k = 2; k <= nfr; k++) - AVI_write_frame(avi, "", 0, 0); - } + nfr = irnd((double)duration / 1000000.0 * fps / 1000.0); + for (k = 2; k <= nfr; k++) + AVI_write_frame(avi, "", 0, 0); } } diff --git a/src/extract/xtr_avi.h b/src/extract/xtr_avi.h index f86f42454..7102c6d55 100644 --- a/src/extract/xtr_avi.h +++ b/src/extract/xtr_avi.h @@ -33,9 +33,10 @@ public: xtr_avi_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_file(); }; diff --git a/src/extract/xtr_base.cpp b/src/extract/xtr_base.cpp index bd3c63320..84a5b6d48 100644 --- a/src/extract/xtr_base.cpp +++ b/src/extract/xtr_base.cpp @@ -69,19 +69,50 @@ xtr_base_c::create_file(xtr_base_c *_master, } void -xtr_base_c::handle_block(KaxBlock &block, +xtr_base_c::handle_block_v1(KaxBlock &block, + KaxBlockAdditions *additions, + int64_t timecode, + int64_t duration, + int64_t bref, + int64_t fref) { + int i; + + if (0 == block.NumberFrames()) + return; + + if (0 > duration) + duration = default_duration * block.NumberFrames(); + + for (i = 0; i < block.NumberFrames(); i++) { + int64_t this_timecode, this_duration; + + if (0 > duration) { + this_timecode = timecode; + this_duration = duration; + } else { + this_timecode = timecode + i * duration / block.NumberFrames(); + this_duration = duration / block.NumberFrames(); + } + + DataBuffer &data = block.GetBuffer(i); + memory_cptr frame(new memory_c(data.Buffer(), data.Size(), false)); + handle_frame(frame, additions, this_timecode, this_duration, bref, fref, + false, false, true); + } +} + +void +xtr_base_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { - int i; - - for (i = 0; i < block.NumberFrames(); i++) { - DataBuffer &data = block.GetBuffer(i); - out->write(data.Buffer(), data.Size()); - bytes_written += data.Size(); - } + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { + out->write(frame->get(), frame->get_size()); + bytes_written += frame->get_size(); } void diff --git a/src/extract/xtr_base.h b/src/extract/xtr_base.h index 66964c334..ae4427665 100644 --- a/src/extract/xtr_base.h +++ b/src/extract/xtr_base.h @@ -45,9 +45,13 @@ public: virtual ~xtr_base_c(); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_block_v1(KaxBlock &block, KaxBlockAdditions *additions, + int64_t timecode, int64_t duration, int64_t bref, + int64_t fref); + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_track(); virtual void finish_file(); diff --git a/src/extract/xtr_ogg.cpp b/src/extract/xtr_ogg.cpp index 40410c72d..80997c5c9 100644 --- a/src/extract/xtr_ogg.cpp +++ b/src/extract/xtr_ogg.cpp @@ -50,7 +50,7 @@ xtr_oggbase_c::xtr_oggbase_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec): xtr_base_c(_codec_id, _tid, tspec), - packetno(2), buffered_data(NULL), buffered_size(0), previous_end(0) { + packetno(2), previous_end(0) { } void @@ -67,40 +67,31 @@ xtr_oggbase_c::create_file(xtr_base_c *_master, } void -xtr_oggbase_c::handle_block(KaxBlock &block, +xtr_oggbase_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { - int i; + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { + if (NULL != buffered_data.get()) { + ogg_packet op; - if (-1 == duration) - duration = default_duration * block.NumberFrames(); + op.b_o_s = 0; + op.e_o_s = 0; + op.packetno = packetno; + op.packet = buffered_data->get(); + op.bytes = buffered_data->get_size(); + op.granulepos = timecode * sfreq / 1000000000; + ogg_stream_packetin(&os, &op); + write_pages(); - for (i = 0; i < block.NumberFrames(); i++) { - DataBuffer &data = block.GetBuffer(i); - if (NULL != buffered_data) { - ogg_packet op; - - op.b_o_s = 0; - op.e_o_s = 0; - op.packetno = packetno; - op.packet = buffered_data; - op.bytes = buffered_size; -// op.granulepos = (timecode / 1000000) * sfreq / 1000; - op.granulepos = (timecode + i * duration / block.NumberFrames()) * - sfreq / 1000000000; - ogg_stream_packetin(&os, &op); - write_pages(); - safefree(buffered_data); - - packetno++; - } - - buffered_data = (unsigned char *)safememdup(data.Buffer(), data.Size()); - buffered_size = data.Size(); + packetno++; } + + buffered_data = memory_cptr(frame->clone()); previous_end = timecode + duration; } @@ -108,7 +99,7 @@ void xtr_oggbase_c::finish_file() { ogg_packet op; - if (NULL == buffered_data) + if (NULL == buffered_data.get()) return; // Set the "end of stream" marker on the last packet, handle it @@ -116,12 +107,11 @@ xtr_oggbase_c::finish_file() { op.b_o_s = 0; op.e_o_s = 1; op.packetno = packetno; - op.packet = buffered_data; - op.bytes = buffered_size; + op.packet = buffered_data->get(); + op.bytes = buffered_data->get_size(); // op.granulepos = (previous_end / 1000000) * sfreq / 1000; op.granulepos = previous_end * sfreq / 1000000000; ogg_stream_packetin(&os, &op); - safefree(buffered_data); flush_pages(); ogg_stream_clear(&os); } diff --git a/src/extract/xtr_ogg.h b/src/extract/xtr_ogg.h index 9dbbe9515..a09cad1a3 100644 --- a/src/extract/xtr_ogg.h +++ b/src/extract/xtr_ogg.h @@ -32,8 +32,7 @@ class xtr_oggbase_c: public xtr_base_c { public: ogg_stream_state os; int packetno; - unsigned char *buffered_data; - int buffered_size; + memory_cptr buffered_data; int sfreq; int64_t previous_end; @@ -41,9 +40,10 @@ public: xtr_oggbase_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_file(); virtual void write_pages(); diff --git a/src/extract/xtr_rmff.cpp b/src/extract/xtr_rmff.cpp index 6c5cf06c7..de9ba0075 100644 --- a/src/extract/xtr_rmff.cpp +++ b/src/extract/xtr_rmff.cpp @@ -61,31 +61,31 @@ xtr_rmff_c::create_file(xtr_base_c *_master, } void -xtr_rmff_c::handle_block(KaxBlock &block, +xtr_rmff_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { - int i; - rmff_frame_t *frame; + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { + rmff_frame_t *rmff_frame; - for (i = 0; i < block.NumberFrames(); i++) { - DataBuffer &data = block.GetBuffer(i); - - frame = rmff_allocate_frame(data.Size(), data.Buffer()); - if (frame == NULL) - mxerror("Memory for a RealAudio/RealVideo frame could not be " - "allocated.\n"); - frame->timecode = timecode / 1000000; - if (0 == bref) - frame->flags = RMFF_FRAME_FLAG_KEYFRAME; - if ('V' == codec_id[0]) - rmff_write_packed_video_frame(rmtrack, frame); - else - rmff_write_frame(rmtrack, frame); - rmff_release_frame(frame); - } + rmff_frame = rmff_allocate_frame(frame->get_size(), frame->get()); + if (rmff_frame == NULL) + mxerror("Memory for a RealAudio/RealVideo frame could not be " + "allocated.\n"); + rmff_frame->timecode = timecode / 1000000; + if (references_valid) + keyframe = 0 == bref; + if (keyframe) + rmff_frame->flags = RMFF_FRAME_FLAG_KEYFRAME; + if ('V' == codec_id[0]) + rmff_write_packed_video_frame(rmtrack, rmff_frame); + else + rmff_write_frame(rmtrack, rmff_frame); + rmff_release_frame(rmff_frame); } void diff --git a/src/extract/xtr_rmff.h b/src/extract/xtr_rmff.h index 74db40df2..9400a390e 100644 --- a/src/extract/xtr_rmff.h +++ b/src/extract/xtr_rmff.h @@ -30,9 +30,10 @@ public: xtr_rmff_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_file(); virtual void headers_done(); }; diff --git a/src/extract/xtr_textsubs.cpp b/src/extract/xtr_textsubs.cpp index cca8eed28..bf81a25df 100644 --- a/src/extract/xtr_textsubs.cpp +++ b/src/extract/xtr_textsubs.cpp @@ -44,12 +44,15 @@ xtr_srt_c::create_file(xtr_base_c *_master, #define LLD03 "%03" PRId64 void -xtr_srt_c::handle_block(KaxBlock &block, +xtr_srt_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { char *text; int64_t start, end; string buffer; @@ -60,15 +63,13 @@ xtr_srt_c::handle_block(KaxBlock &block, duration = 1000000000; } - DataBuffer &data = block.GetBuffer(0); - start = timecode / 1000000; end = start + duration / 1000000; ++num_entries; - text = new char[data.Size() + 1]; - memcpy(text, data.Buffer(), data.Size()); - text[data.Size()] = 0; + text = new char[frame->get_size() + 1]; + memcpy(text, frame->get(), frame->get_size()); + text[frame->get_size()] = 0; buffer = mxsprintf("%d\n" LLD02 ":" LLD02 ":" LLD02 "," LLD03 " --> " LLD02 ":" LLD02 ":" LLD02 "," LLD03 "\n" @@ -177,12 +178,15 @@ xtr_ssa_c::create_file(xtr_base_c *_master, } void -xtr_ssa_c::handle_block(KaxBlock &block, +xtr_ssa_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { int i, k, num; char *s; vector fields; @@ -199,11 +203,10 @@ xtr_ssa_c::handle_block(KaxBlock &block, start = timecode / 1000000; end = start + duration / 1000000; - DataBuffer &data = block.GetBuffer(0); - s = (char *)safemalloc(data.Size() + 1); + s = (char *)safemalloc(frame->get_size() + 1); memory_c af_s((unsigned char *)s, 0, true); - memcpy(s, data.Buffer(), data.Size()); - s[data.Size()] = 0; + memcpy(s, frame->get(), frame->get_size()); + s[frame->get_size()] = 0; // Split the line into the fields. // Specs say that the following fields are to put into the block: @@ -374,21 +377,18 @@ xtr_usf_c::create_file(xtr_base_c *_master, } void -xtr_usf_c::handle_block(KaxBlock &block, +xtr_usf_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { - if (0 == block.NumberFrames()) - return; - - DataBuffer &data_buffer = block.GetBuffer(0); + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { usf_entry_t entry("", timecode, timecode + duration); - memory_cptr data(new memory_c(data_buffer.Buffer(), data_buffer.Size(), - false)); - content_decoder.reverse(data, CONTENT_ENCODING_SCOPE_BLOCK); - entry.m_text.append((const char *)data->get(), data->get_size()); + content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK); + entry.m_text.append((const char *)frame->get(), frame->get_size()); m_entries.push_back(entry); } diff --git a/src/extract/xtr_textsubs.h b/src/extract/xtr_textsubs.h index 0852da651..c0ee1a856 100644 --- a/src/extract/xtr_textsubs.h +++ b/src/extract/xtr_textsubs.h @@ -36,9 +36,10 @@ public: xtr_srt_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); }; class xtr_ssa_c: public xtr_base_c { @@ -65,9 +66,10 @@ public: xtr_ssa_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_file(); }; @@ -89,9 +91,10 @@ public: xtr_usf_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_track(); virtual void finish_file(); }; diff --git a/src/extract/xtr_tta.cpp b/src/extract/xtr_tta.cpp index 7e0bb4427..2fd7622e6 100644 --- a/src/extract/xtr_tta.cpp +++ b/src/extract/xtr_tta.cpp @@ -48,20 +48,17 @@ xtr_tta_c::create_file(xtr_base_c *_master, } void -xtr_tta_c::handle_block(KaxBlock &block, +xtr_tta_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { - int i; - - for (i = 0; i < block.NumberFrames(); i++) { - DataBuffer &data = block.GetBuffer(i); - - frame_sizes.push_back(data.Size()); - out->write(data.Buffer(), data.Size()); - } + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { + frame_sizes.push_back(frame->get_size()); + out->write(frame->get(), frame->get_size()); if (0 < duration) last_duration = duration; diff --git a/src/extract/xtr_tta.h b/src/extract/xtr_tta.h index b98ad3add..7036c2a11 100644 --- a/src/extract/xtr_tta.h +++ b/src/extract/xtr_tta.h @@ -32,9 +32,10 @@ public: xtr_tta_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_file(); }; diff --git a/src/extract/xtr_vobsub.cpp b/src/extract/xtr_vobsub.cpp index 346b61bc7..f2d84765f 100644 --- a/src/extract/xtr_vobsub.cpp +++ b/src/extract/xtr_vobsub.cpp @@ -115,122 +115,118 @@ xtr_vobsub_c::create_file(xtr_base_c *_master, } void -xtr_vobsub_c::handle_block(KaxBlock &block, +xtr_vobsub_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { static unsigned char padding_data[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; mpeg_es_header_t es; mpeg_ps_header_t ps; uint64_t c; - int i; + uint32_t size, padding, first; xtr_vobsub_c *vmaster; + unsigned char *data; if (NULL == master) vmaster = this; else vmaster = static_cast(master); - for (i = 0; i < block.NumberFrames(); i++) { - uint32_t size, padding, first; - DataBuffer &data_buffer = block.GetBuffer(i); - memory_cptr data_m(new memory_c(data_buffer.Buffer(), data_buffer.Size(), - false)); - unsigned char *data; + content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK); + data = frame->get(); + size = frame->get_size(); - content_decoder.reverse(data_m, CONTENT_ENCODING_SCOPE_BLOCK); - data = data_m->get(); - size = data_m->get_size(); + positions.push_back(vmaster->out->getFilePointer()); + timecodes.push_back(timecode); - positions.push_back(vmaster->out->getFilePointer()); - timecodes.push_back(timecode); + padding = (2048 - (size + sizeof(mpeg_ps_header_t) + + sizeof(mpeg_es_header_t))) & 2047; + first = size + sizeof(mpeg_ps_header_t) + + sizeof(mpeg_es_header_t) > 2048 ? + 2048 - sizeof(mpeg_ps_header_t) - sizeof(mpeg_es_header_t) : size; - padding = (2048 - (size + sizeof(mpeg_ps_header_t) + - sizeof(mpeg_es_header_t))) & 2047; - first = size + sizeof(mpeg_ps_header_t) + - sizeof(mpeg_es_header_t) > 2048 ? - 2048 - sizeof(mpeg_ps_header_t) - sizeof(mpeg_es_header_t) : size; + memset(&ps, 0, sizeof(mpeg_ps_header_t)); - memset(&ps, 0, sizeof(mpeg_ps_header_t)); + ps.pfx[2] = 0x01; + ps.pfx[3] = 0xba; + c = timecode * 9 / 100000; - ps.pfx[2] = 0x01; - ps.pfx[3] = 0xba; - c = timecode * 9 / 100000; + ps.scr[0] = 0x40 | ((uint8_t)(c >> 27) & 0x38) | 0x04 | + ((uint8_t)(c >> 28) & 0x03); + ps.scr[1] = (uint8_t)(c >> 20); + ps.scr[2] = ((uint8_t)(c >> 12) & 0xf8) | 0x04 | + ((uint8_t)(c >> 13) & 0x03); + ps.scr[3] = (uint8_t)(c >> 5); + ps.scr[4] = ((uint8_t)(c << 3) & 0xf8) | 0x04; + ps.scr[5] = 1; + ps.muxr[0] = 1; + ps.muxr[1] = 0x89; + ps.muxr[2] = 0xc3; // just some value + ps.stlen = 0xf8; + if ((padding < 8) && (first == size)) + ps.stlen |= (uint8_t)padding; + + memset(&es, 0, sizeof(mpeg_es_header_t)); + es.pfx[2] = 1; + es.stream_id = 0xbd; + es.len[0] = (uint8_t)((first + 9) >> 8); + es.len[1] = (uint8_t)(first + 9); + es.flags[0] = 0x81; + es.flags[1] = 0x80; + es.hlen = 5; + es.pts[0] = 0x20 | ((uint8_t)(c >> 29) & 0x0e) | 0x01; + es.pts[1] = (uint8_t)(c >> 22); + es.pts[2] = ((uint8_t)(c >> 14) & 0xfe) | 0x01; + es.pts[3] = (uint8_t)(c >> 7); + es.pts[4] = (uint8_t)(c << 1) | 0x01; + if (NULL == master) + es.lidx = 0x20; + else + es.lidx = stream_id; + + vmaster->out->write(&ps, sizeof(mpeg_ps_header_t)); + if ((padding > 0) && (padding < 8) && (first == size)) + vmaster->out->write(padding_data, padding); + vmaster->out->write(&es, sizeof(mpeg_es_header_t)); + vmaster->out->write(data, first); + while (first < size) { + size -= first; + data += first; + + padding = (2048 - (size + 10 + sizeof(mpeg_ps_header_t))) & 2047; + first = size + 10 + sizeof(mpeg_ps_header_t) > 2048 ? + 2048 - 10 - sizeof(mpeg_ps_header_t) : size; - ps.scr[0] = 0x40 | ((uint8_t)(c >> 27) & 0x38) | 0x04 | - ((uint8_t)(c >> 28) & 0x03); - ps.scr[1] = (uint8_t)(c >> 20); - ps.scr[2] = ((uint8_t)(c >> 12) & 0xf8) | 0x04 | - ((uint8_t)(c >> 13) & 0x03); - ps.scr[3] = (uint8_t)(c >> 5); - ps.scr[4] = ((uint8_t)(c << 3) & 0xf8) | 0x04; - ps.scr[5] = 1; - ps.muxr[0] = 1; - ps.muxr[1] = 0x89; - ps.muxr[2] = 0xc3; // just some value - ps.stlen = 0xf8; if ((padding < 8) && (first == size)) ps.stlen |= (uint8_t)padding; - memset(&es, 0, sizeof(mpeg_es_header_t)); - es.pfx[2] = 1; - es.stream_id = 0xbd; - es.len[0] = (uint8_t)((first + 9) >> 8); - es.len[1] = (uint8_t)(first + 9); - es.flags[0] = 0x81; - es.flags[1] = 0x80; - es.hlen = 5; - es.pts[0] = 0x20 | ((uint8_t)(c >> 29) & 0x0e) | 0x01; - es.pts[1] = (uint8_t)(c >> 22); - es.pts[2] = ((uint8_t)(c >> 14) & 0xfe) | 0x01; - es.pts[3] = (uint8_t)(c >> 7); - es.pts[4] = (uint8_t)(c << 1) | 0x01; - if (NULL == master) - es.lidx = 0x20; - else - es.lidx = stream_id; - + es.len[0] = (uint8_t)((first + 4) >> 8); + es.len[1] = (uint8_t)(first + 4); + es.flags[1] = 0; + es.hlen = 0; + es.pts[0] = es.lidx; vmaster->out->write(&ps, sizeof(mpeg_ps_header_t)); if ((padding > 0) && (padding < 8) && (first == size)) vmaster->out->write(padding_data, padding); - vmaster->out->write(&es, sizeof(mpeg_es_header_t)); + vmaster->out->write(&es, 10); vmaster->out->write(data, first); - while (first < size) { - size -= first; - data += first; - - padding = (2048 - (size + 10 + sizeof(mpeg_ps_header_t))) & 2047; - first = size + 10 + sizeof(mpeg_ps_header_t) > 2048 ? - 2048 - 10 - sizeof(mpeg_ps_header_t) : size; - - if ((padding < 8) && (first == size)) - ps.stlen |= (uint8_t)padding; - - es.len[0] = (uint8_t)((first + 4) >> 8); - es.len[1] = (uint8_t)(first + 4); - es.flags[1] = 0; - es.hlen = 0; - es.pts[0] = es.lidx; - vmaster->out->write(&ps, sizeof(mpeg_ps_header_t)); - if ((padding > 0) && (padding < 8) && (first == size)) - vmaster->out->write(padding_data, padding); - vmaster->out->write(&es, 10); - vmaster->out->write(data, first); - } - if (8 <= padding) { - padding -= 6; - es.stream_id = 0xbe; - es.len[0] = (uint8_t)(padding >> 8); - es.len[1] = (uint8_t)padding; - vmaster->out->write(&es, 6); // XXX - while (0 < padding) { - uint32_t todo = padding > 8 ? 8 : padding; - vmaster->out->write(padding_data, todo); - padding -= todo; - } + } + if (8 <= padding) { + padding -= 6; + es.stream_id = 0xbe; + es.len[0] = (uint8_t)(padding >> 8); + es.len[1] = (uint8_t)padding; + vmaster->out->write(&es, 6); // XXX + while (0 < padding) { + uint32_t todo = padding > 8 ? 8 : padding; + vmaster->out->write(padding_data, todo); + padding -= todo; } } } diff --git a/src/extract/xtr_vobsub.h b/src/extract/xtr_vobsub.h index 79c4764cb..8fbf792f0 100644 --- a/src/extract/xtr_vobsub.h +++ b/src/extract/xtr_vobsub.h @@ -33,9 +33,10 @@ public: xtr_vobsub_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_file(); virtual void write_idx(mm_io_c &idx, int index); }; diff --git a/src/extract/xtr_wav.cpp b/src/extract/xtr_wav.cpp index b6398bcc8..32cdf951b 100644 --- a/src/extract/xtr_wav.cpp +++ b/src/extract/xtr_wav.cpp @@ -110,102 +110,101 @@ xtr_wavpack4_c::create_file(xtr_base_c *_master, } void -xtr_wavpack4_c::handle_block(KaxBlock &block, +xtr_wavpack4_c::handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref) { + int64_t fref, + bool keyframe, + bool discardable, + bool references_valid) { binary wv_header[32], *mybuffer; - int i, data_size; + int data_size; vector flags; - for (i = 0; i < block.NumberFrames(); i++) { - DataBuffer &data = block.GetBuffer(i); + // build the main header - // build the main header + wv_header[0] = 'w'; + wv_header[1] = 'v'; + wv_header[2] = 'p'; + wv_header[3] = 'k'; + memcpy(&wv_header[8], version, 2); // version + wv_header[10] = 0; // track_no + wv_header[11] = 0; // index_no + wv_header[12] = 0xFF; // total_samples is unknown + wv_header[13] = 0xFF; + wv_header[14] = 0xFF; + wv_header[15] = 0xFF; + put_uint32_le(&wv_header[16], number_of_samples); // block_index + mybuffer = frame->get(); + data_size = frame->get_size(); + number_of_samples += get_uint32_le(mybuffer); - wv_header[0] = 'w'; - wv_header[1] = 'v'; - wv_header[2] = 'p'; - wv_header[3] = 'k'; - memcpy(&wv_header[8], version, 2); // version - wv_header[10] = 0; // track_no - wv_header[11] = 0; // index_no - wv_header[12] = 0xFF; // total_samples is unknown - wv_header[13] = 0xFF; - wv_header[14] = 0xFF; - wv_header[15] = 0xFF; - put_uint32_le(&wv_header[16], number_of_samples); // block_index - mybuffer = data.Buffer(); - data_size = data.Size(); - number_of_samples += get_uint32_le(mybuffer); + // rest of the header: + memcpy(&wv_header[20], mybuffer, 3 * sizeof(uint32_t)); + // support multi-track files + if (channels > 2) { + uint32_t block_size = get_uint32_le(&mybuffer[12]); - // rest of the header: - memcpy(&wv_header[20], mybuffer, 3 * sizeof(uint32_t)); - // support multi-track files - if (channels > 2) { - uint32_t block_size = get_uint32_le(&mybuffer[12]); - - flags.clear(); - put_uint32_le(&wv_header[4], block_size + 24); // ck_size + flags.clear(); + put_uint32_le(&wv_header[4], block_size + 24); // ck_size + out->write(wv_header, 32); + flags.push_back(*(uint32_t *)&mybuffer[4]); + mybuffer += 16; + out->write(mybuffer, block_size); + mybuffer += block_size; + data_size -= block_size + 16; + while (data_size > 0) { + block_size = get_uint32_le(&mybuffer[8]); + memcpy(&wv_header[24], mybuffer, 8); + put_uint32_le(&wv_header[4], block_size + 24); out->write(wv_header, 32); - flags.push_back(*(uint32_t *)&mybuffer[4]); - mybuffer += 16; + flags.push_back(*(uint32_t *)mybuffer); + mybuffer += 12; out->write(mybuffer, block_size); mybuffer += block_size; - data_size -= block_size + 16; - while (data_size > 0) { - block_size = get_uint32_le(&mybuffer[8]); - memcpy(&wv_header[24], mybuffer, 8); - put_uint32_le(&wv_header[4], block_size + 24); - out->write(wv_header, 32); - flags.push_back(*(uint32_t *)mybuffer); - mybuffer += 12; - out->write(mybuffer, block_size); - mybuffer += block_size; - data_size -= block_size + 12; - } - } else { - put_uint32_le(&wv_header[4], data_size + 12); // ck_size - out->write(wv_header, 32); - out->write(&mybuffer[12], data_size - 12); // the rest of the + data_size -= block_size + 12; } + } else { + put_uint32_le(&wv_header[4], data_size + 12); // ck_size + out->write(wv_header, 32); + out->write(&mybuffer[12], data_size - 12); // the rest of the + } - // support hybrid mode data - if ((NULL != corr_out) && (NULL != additions)) { - KaxBlockMore *block_more = FINDFIRST(additions, KaxBlockMore); + // support hybrid mode data + if ((NULL != corr_out) && (NULL != additions)) { + KaxBlockMore *block_more = FINDFIRST(additions, KaxBlockMore); - if (block_more == NULL) - break; - KaxBlockAdditional *block_addition = - FINDFIRST(block_more, KaxBlockAdditional); - if (block_addition == NULL) - break; + if (block_more == NULL) + return; + KaxBlockAdditional *block_addition = + FINDFIRST(block_more, KaxBlockAdditional); + if (block_addition == NULL) + return; - data_size = block_addition->GetSize(); - mybuffer = block_addition->GetBuffer(); - if (channels > 2) { - size_t flags_index = 0; + data_size = block_addition->GetSize(); + mybuffer = block_addition->GetBuffer(); + if (channels > 2) { + size_t flags_index = 0; - while (data_size > 0) { - uint32_t block_size = get_uint32_le(&mybuffer[4]); + while (data_size > 0) { + uint32_t block_size = get_uint32_le(&mybuffer[4]); - put_uint32_le(&wv_header[4], block_size + 24); // ck_size - memcpy(&wv_header[24], &flags[flags_index++], 4); // flags - memcpy(&wv_header[28], mybuffer, 4); // crc - corr_out->write(wv_header, 32); - mybuffer += 8; - corr_out->write(mybuffer, block_size); - mybuffer += block_size; - data_size -= 8 + block_size; - } - } else { - put_uint32_le(&wv_header[4], data_size + 20); // ck_size + put_uint32_le(&wv_header[4], block_size + 24); // ck_size + memcpy(&wv_header[24], &flags[flags_index++], 4); // flags memcpy(&wv_header[28], mybuffer, 4); // crc corr_out->write(wv_header, 32); - corr_out->write(&mybuffer[4], data_size - 4); + mybuffer += 8; + corr_out->write(mybuffer, block_size); + mybuffer += block_size; + data_size -= 8 + block_size; } + } else { + put_uint32_le(&wv_header[4], data_size + 20); // ck_size + memcpy(&wv_header[28], mybuffer, 4); // crc + corr_out->write(wv_header, 32); + corr_out->write(&mybuffer[4], data_size - 4); } } } diff --git a/src/extract/xtr_wav.h b/src/extract/xtr_wav.h index 1aadc2410..f3a4b85ed 100644 --- a/src/extract/xtr_wav.h +++ b/src/extract/xtr_wav.h @@ -42,9 +42,10 @@ public: xtr_wavpack4_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions, + virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions, int64_t timecode, int64_t duration, int64_t bref, - int64_t fref); + int64_t fref, bool keyframe, bool discardable, + bool references_valid); virtual void finish_file(); };