static void handle_blockgroup(KaxBlockGroup &blockgroup, KaxCluster &cluster, int64_t tc_scale) { // Only continue if this block group actually contains a block. KaxBlock *block = FINDFIRST(&blockgroup, KaxBlock); if ((NULL == block) || (0 == block->NumberFrames())) return; block->SetParent(cluster); // Do we need this block group? xtr_base_c *extractor = NULL; size_t i; for (i = 0; i < extractors.size(); i++) if (block->TrackNum() == extractors[i]->m_track_num) { extractor = extractors[i]; break; } if (NULL == extractor) return; // Next find the block duration if there is one. KaxBlockDuration *kduration = FINDFIRST(&blockgroup, KaxBlockDuration); int64_t duration = NULL == kduration ? -1 : (int64_t)uint64(*kduration) * tc_scale; // Now find backward and forward references. int64_t bref = 0; int64_t fref = 0; KaxReferenceBlock *kreference = FINDFIRST(&blockgroup, KaxReferenceBlock); for (i = 0; (2 > i) && (NULL != kreference); i++) { if (0 > int64(*kreference)) bref = int64(*kreference); else fref = int64(*kreference); kreference = FINDNEXT(&blockgroup, KaxReferenceBlock, kreference); } // Any block additions present? KaxBlockAdditions *kadditions = FINDFIRST(&blockgroup, KaxBlockAdditions); if (0 > duration) duration = extractor->m_default_duration * block->NumberFrames(); KaxCodecState *kcstate = FINDFIRST(&blockgroup, KaxCodecState); if (NULL != kcstate) { memory_cptr codec_state(new memory_c(kcstate->GetBuffer(), kcstate->GetSize(), false)); extractor->handle_codec_state(codec_state); } 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 int64_t handle_blockgroup(KaxBlockGroup &blockgroup, KaxCluster &cluster, int64_t tc_scale) { // Only continue if this block group actually contains a block. KaxBlock *block = FindChild<KaxBlock>(&blockgroup); if (!block || (0 == block->NumberFrames())) return -1; block->SetParent(cluster); handle_blockgroup_timestamps(blockgroup, tc_scale); // Do we need this block group? auto extractor_itr = track_extractors_by_track_number.find(block->TrackNum()); if (extractor_itr == track_extractors_by_track_number.end()) return -1; // Next find the block duration if there is one. auto &extractor = *extractor_itr->second; KaxBlockDuration *kduration = FindChild<KaxBlockDuration>(&blockgroup); int64_t duration = !kduration ? -1 : static_cast<int64_t>(kduration->GetValue() * tc_scale); int64_t max_timestamp = 0; // Now find backward and forward references. int64_t bref = 0; int64_t fref = 0; auto kreference = FindChild<KaxReferenceBlock>(&blockgroup); for (int i = 0; (2 > i) && kreference; i++) { if (0 > kreference->GetValue()) bref = kreference->GetValue(); else fref = kreference->GetValue(); kreference = FindNextChild(blockgroup, *kreference); } // Any block additions present? KaxBlockAdditions *kadditions = FindChild<KaxBlockAdditions>(&blockgroup); if (0 > duration) duration = extractor.m_default_duration * block->NumberFrames(); KaxCodecState *kcstate = FindChild<KaxCodecState>(&blockgroup); if (kcstate) { memory_cptr codec_state(new memory_c(kcstate->GetBuffer(), kcstate->GetSize(), false)); extractor.handle_codec_state(codec_state); } for (int i = 0, num_frames = block->NumberFrames(); i < num_frames; i++) { int64_t this_timestamp, this_duration; if (0 > duration) { this_timestamp = block->GlobalTimecode(); this_duration = duration; } else { this_timestamp = block->GlobalTimecode() + i * duration / block->NumberFrames(); this_duration = duration / block->NumberFrames(); } auto discard_padding = timestamp_c::ns(0); auto kdiscard_padding = FindChild<KaxDiscardPadding>(blockgroup); if (kdiscard_padding) discard_padding = timestamp_c::ns(kdiscard_padding->GetValue()); auto &data = block->GetBuffer(i); auto frame = std::make_shared<memory_c>(data.Buffer(), data.Size(), false); auto f = xtr_frame_t{frame, kadditions, this_timestamp, this_duration, bref, fref, false, false, true, discard_padding}; extractor.decode_and_handle_frame(f); max_timestamp = std::max(max_timestamp, this_timestamp); } return max_timestamp; }
static int64_t handle_blockgroup(KaxBlockGroup &blockgroup, KaxCluster &cluster, int64_t tc_scale) { // Only continue if this block group actually contains a block. KaxBlock *block = FindChild<KaxBlock>(&blockgroup); if (!block || (0 == block->NumberFrames())) return -1; block->SetParent(cluster); // Do we need this block group? xtr_base_c *extractor = nullptr; size_t i; for (i = 0; i < extractors.size(); i++) if (block->TrackNum() == extractors[i]->m_track_num) { extractor = extractors[i]; break; } if (!extractor) return -1; // Next find the block duration if there is one. KaxBlockDuration *kduration = FindChild<KaxBlockDuration>(&blockgroup); int64_t duration = !kduration ? -1 : static_cast<int64_t>(kduration->GetValue() * tc_scale); int64_t max_timecode = 0; // Now find backward and forward references. int64_t bref = 0; int64_t fref = 0; auto kreference = FindChild<KaxReferenceBlock>(&blockgroup); for (i = 0; (2 > i) && kreference; i++) { if (0 > kreference->GetValue()) bref = kreference->GetValue(); else fref = kreference->GetValue(); kreference = FindNextChild<KaxReferenceBlock>(&blockgroup, kreference); } // Any block additions present? KaxBlockAdditions *kadditions = FindChild<KaxBlockAdditions>(&blockgroup); if (0 > duration) duration = extractor->m_default_duration * block->NumberFrames(); KaxCodecState *kcstate = FindChild<KaxCodecState>(&blockgroup); if (kcstate) { memory_cptr codec_state(new memory_c(kcstate->GetBuffer(), kcstate->GetSize(), false)); extractor->handle_codec_state(codec_state); } 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); max_timecode = std::max(max_timecode, this_timecode); } return max_timecode; }