Example #1
0
void
SegmentSeeker::index_unsearched_range( matroska_segment_c& ms, Range search_area, mtime_t max_pts )
{
    mkv_jump_to( ms, search_area.start );

    search_area.start = ms.es.I_O().getFilePointer();

    fptr_t  block_pos = search_area.start;
    mtime_t block_pts = std::numeric_limits<mtime_t>::max();

    while( block_pos < search_area.end )
    {
        KaxBlock * block;
        KaxSimpleBlock * simpleblock;

        bool     b_key_picture;
        bool     b_discardable_picture;
        int64_t  i_block_duration;

        matroska_segment_c::tracks_map_t::iterator i_track = ms.tracks.end();

        if( ms.BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) )
        {
            throw std::runtime_error( "Unable to BlockGet in SegmentSeeker::index_unsearched_range, EOF?" );
        }

        if( simpleblock ) {
            block_pos = simpleblock->GetElementPosition();
            block_pts = simpleblock->GlobalTimecode() / 1000;
        }
        else {
            block_pos = block->GetElementPosition();
            block_pts = block->GlobalTimecode() / 1000;
        }

        if( ! ms.FindTrackByBlock( &i_track, block, simpleblock ) )
        {
            if( b_key_picture )
            {
                add_seekpoint( i_track->first, Seekpoint::TRUSTED, block_pos, block_pts );
            }

            if( max_pts < block_pts )
                break;
        }

        delete block;
    }

    search_area.end = ms.es.I_O().getFilePointer();

    mark_range_as_searched( search_area );
}
Example #2
0
static void
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)
        return;
    block->SetParent(cluster);

    // Do we need this block group?
    std::vector<timecode_extractor_t>::iterator extractor = find_extractor_by_track_number(block->TrackNum());
    if (timecode_extractors.end() == extractor)
        return;

    // Next find the block duration if there is one.
    KaxBlockDuration *kduration = FindChild<KaxBlockDuration>(&blockgroup);
    int64_t duration            = !kduration ? extractor->m_default_duration * block->NumberFrames() : kduration->GetValue() * tc_scale;

    // Pass the block to the extractor.
    size_t i;
    for (i = 0; block->NumberFrames() > i; ++i)
        extractor->m_timecodes.push_back(timecode_t(block->GlobalTimecode() + i * duration / block->NumberFrames(), duration / block->NumberFrames()));
}
Example #3
0
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);
  }
}
Example #4
0
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;
}
Example #5
0
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;
}