diff --git a/ChangeLog b/ChangeLog index ec013ee9f..9fa07b298 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2005-10-21 Moritz Bunkus + * mkvextract: new feature: Added support for the new SimpleBlock. + * mkvmerge, mmg: new feature: Added support for the new SimpleBlock instead of BlockGroups (only available via "--engage use_simpleblock" for now). Patch by Steve Lhomme (see AUTHORS) diff --git a/src/extract/tracks.cpp b/src/extract/tracks.cpp index 79a7c1bff..fce4a28ab 100644 --- a/src/extract/tracks.cpp +++ b/src/extract/tracks.cpp @@ -158,8 +158,9 @@ handle_blockgroup(KaxBlockGroup &blockgroup, // Only continue if this block group actually contains a block. block = FINDFIRST(&blockgroup, KaxBlock); - if (NULL == block) + if ((NULL == block) || (0 == block->NumberFrames())) return; + block->SetParent(cluster); // Do we need this block group? @@ -194,9 +195,71 @@ handle_blockgroup(KaxBlockGroup &blockgroup, // Any block additions present? kadditions = FINDFIRST(&blockgroup, KaxBlockAdditions); - // Pass the block to the extractor. - extractor->handle_block_v1(*block, kadditions, block->GlobalTimecode(), - duration, bref, fref); + if (0 > duration) + duration = extractor->default_duration * block->NumberFrames(); + + for (i = 0; i < block->NumberFrames(); i++) { + int64_t this_timecode, this_duration; + + if (0 > duration) { + this_timecode = block->GlobalTimecode(); + this_duration = duration; + } else { + this_timecode = block->GlobalTimecode() + 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)); + extractor->handle_frame(frame, kadditions, this_timecode, this_duration, + bref, fref, false, false, true); + } +} + +static void +handle_simpleblock(KaxSimpleBlock &simpleblock, + KaxCluster &cluster) { + xtr_base_c *extractor; + int64_t duration; + size_t i; + + if (0 == simpleblock.NumberFrames()) + return; + + simpleblock.SetParent(cluster); + + // Do we need this block group? + extractor = NULL; + for (i = 0; i < extractors.size(); i++) + if (simpleblock.TrackNum() == extractors[i]->tid) { + extractor = extractors[i]; + break; + } + + if (NULL == extractor) + return; + + duration = extractor->default_duration * simpleblock.NumberFrames(); + + for (i = 0; i < simpleblock.NumberFrames(); i++) { + int64_t this_timecode, this_duration; + + if (0 > duration) { + this_timecode = simpleblock.GlobalTimecode(); + this_duration = duration; + } else { + this_timecode = simpleblock.GlobalTimecode() + i * duration / + simpleblock.NumberFrames(); + this_duration = duration / simpleblock.NumberFrames(); + } + + DataBuffer &data = simpleblock.GetBuffer(i); + memory_cptr frame(new memory_c(data.Buffer(), data.Size(), false)); + extractor->handle_frame(frame, NULL, this_timecode, this_duration, + -1, -1, simpleblock.IsKeyframe(), + simpleblock.IsDiscardable(), false); + } } static void @@ -427,6 +490,13 @@ extract_tracks(const char *file_name, handle_blockgroup(*static_cast(l2), *cluster, tc_scale); + } else if (EbmlId(*l2) == KaxSimpleBlock::ClassInfos.GlobalId) { + show_element(l2, 2, _("SimpleBlock")); + + l2->Read(*es, KaxSimpleBlock::ClassInfos.Context, upper_lvl_el, l3, + true); + handle_simpleblock(*static_cast(l2), *cluster); + } else l2->SkipData(*es, l2->Generic().Context); diff --git a/src/extract/xtr_base.cpp b/src/extract/xtr_base.cpp index 84a5b6d48..47ab0d80f 100644 --- a/src/extract/xtr_base.cpp +++ b/src/extract/xtr_base.cpp @@ -68,39 +68,6 @@ xtr_base_c::create_file(xtr_base_c *_master, default_duration = kt_get_default_duration(track); } -void -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, diff --git a/src/extract/xtr_base.h b/src/extract/xtr_base.h index ae4427665..4b0417aa8 100644 --- a/src/extract/xtr_base.h +++ b/src/extract/xtr_base.h @@ -45,9 +45,6 @@ public: virtual ~xtr_base_c(); virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track); - 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, bool keyframe, bool discardable,