コード例 #1
0
ファイル: mp4_fragment.c プロジェクト: atgsdjb/SeraphBaseCpp
static ctts_t* ctts_create(mp4_context_t const* mp4_context,
													 samples_t const* first, samples_t const* last)
{
	samples_t const* f = first;
	unsigned int i = 0;
	while(f != last)
	{
		if(f->cto_)
			break;
		++f;
	}

	if(f == last)
	{
		return 0;
	}
	else
	{
		unsigned int prev_cto = 0;
		unsigned int samples = last - first;
		ctts_t* ctts = ctts_init();
		ctts->table_ = (ctts_table_t*)
			malloc((samples) * sizeof(ctts_table_t));

		f = first; i = 0;
		prev_cto = f->cto_;
		while(f != last)
		{
			unsigned int sc = 0;
			while(f->cto_ == prev_cto && f != last)
			{
				++sc;
				++f;
			}
			ctts->table_[i].sample_count_ = sc ;
			ctts->table_[i].sample_offset_ = prev_cto;
			prev_cto = f->cto_;
			++i;
		}
		ctts->entries_ = i;
		if(ctts_get_samples(ctts) != samples)
		{
			MP4_WARNING("ERROR: stts_get_samples=%d, should be %d\n",
				ctts_get_samples(ctts), samples);
		}
		return ctts;
	}
}
コード例 #2
0
static void trak_update_index(struct mp4_context_t const* mp4_context,
                              struct trak_t* trak,
                              unsigned int start, unsigned int end)
{
  // write samples [start,end>

  // stts = [entries * [sample_count, sample_duration]
  {
    struct stts_t* stts = trak->mdia_->minf_->stbl_->stts_;

    unsigned int entries = 0;
    unsigned int s = start;

    while(s != end)
    {
      unsigned int sample_count = 1;
      unsigned int sample_duration =
        (unsigned int)(trak->samples_[s + 1].pts_ - trak->samples_[s].pts_);
      while(++s != end)
      {
        if((trak->samples_[s + 1].pts_ - trak->samples_[s].pts_) != sample_duration)
          break;
        ++sample_count;
      }
// TODO: entries may be empty when we read a fragmented movie file. use
// output_mov() instead.
//      if(entries + 1 > stts->entries_)
//      {
//        stts->table_ = (stts_table_t*)
//          realloc(stts->table_, (entries + 1) * sizeof(stts_table_t));
//      }

      stts->table_[entries].sample_count_ = sample_count;
      stts->table_[entries].sample_duration_ = sample_duration;
      ++entries;
    }
    stts->entries_ = entries;

    if(stts_get_samples(stts) != end - start)
    {
      MP4_WARNING("ERROR: stts_get_samples=%d, should be %d\n",
             stts_get_samples(stts), end - start);
    }
  }

  // ctts = [entries * [sample_count, sample_offset]
  {
    struct ctts_t* ctts = trak->mdia_->minf_->stbl_->ctts_;
    if(ctts)
    {
      unsigned int entries = 0;
      unsigned int s = start;

      while(s != end)
      {
        unsigned int sample_count = 1;
        unsigned int sample_offset = trak->samples_[s].cto_;
        while(++s != end)
        {
          if(trak->samples_[s].cto_ != sample_offset)
            break;
          ++sample_count;
        }
        // write entry
        ctts->table_[entries].sample_count_ = sample_count;
        ctts->table_[entries].sample_offset_ = sample_offset;
        ++entries;
      }
      ctts->entries_ = entries;
      if(ctts_get_samples(ctts) != end - start)
      {
        MP4_WARNING("ERROR: ctts_get_samples=%d, should be %d\n",
               ctts_get_samples(ctts), end - start);
      }
    }
  }

  // process chunkmap:
  {
    struct stsc_t* stsc = trak->mdia_->minf_->stbl_->stsc_;
    if(stsc != NULL)
    {
      unsigned int i;

      for(i = 0; i != trak->chunks_size_; ++i)
      {
        if(trak->chunks_[i].sample_ + trak->chunks_[i].size_ > start)
          break;
      }

      {
        unsigned int stsc_entries = 0;
        unsigned int chunk_start = i;
        unsigned int chunk_end;
        // problem.mp4: reported by Jin-seok Lee. Second track contains no samples
        if(trak->chunks_size_ != 0)
        {
          unsigned int samples =
            trak->chunks_[i].sample_ + trak->chunks_[i].size_ - start;
          unsigned int id = trak->chunks_[i].id_;

          // write entry [chunk,samples,id]
          stsc->table_[stsc_entries].chunk_ = 0;
          stsc->table_[stsc_entries].samples_ = samples;
          stsc->table_[stsc_entries].id_ = id;
          ++stsc_entries;

          if(i != trak->chunks_size_)
          {
            for(i += 1; i != trak->chunks_size_; ++i)
            {
              unsigned int next_size = trak->chunks_[i].size_;
              if(trak->chunks_[i].sample_ + trak->chunks_[i].size_ > end)
              {
                next_size = end - trak->chunks_[i].sample_;
              }

              if(next_size != samples)
              {
                samples = next_size;
                id = trak->chunks_[i].id_;
                stsc->table_[stsc_entries].chunk_ = i - chunk_start;
                stsc->table_[stsc_entries].samples_ = samples;
                stsc->table_[stsc_entries].id_ = id;
                ++stsc_entries;
              }

              if(trak->chunks_[i].sample_ + next_size == end)
              {
                break;
              }
            }
          }
        }
        chunk_end = i + 1;
        stsc->entries_ = stsc_entries;

        {
          struct stco_t* stco = trak->mdia_->minf_->stbl_->stco_;
          unsigned int entries = 0;
          for(i = chunk_start; i != chunk_end; ++i)
          {
            stco->chunk_offsets_[entries] = stco->chunk_offsets_[i];
            ++entries;
          }
          stco->entries_ = entries;

          // patch first chunk with correct sample offset
          stco->chunk_offsets_[0] = (uint32_t)trak->samples_[start].pos_;
        }
      }
    }
  }

  // process sync samples:
  if(trak->mdia_->minf_->stbl_->stss_)
  {
    struct stss_t* stss = trak->mdia_->minf_->stbl_->stss_;
    unsigned int entries = 0;
    unsigned int stss_start;
    unsigned int i;

    for(i = 0; i != stss->entries_; ++i)
    {
      if(stss->sample_numbers_[i] >= start + 1)
        break;
    }
    stss_start = i;
    for(; i != stss->entries_; ++i)
    {
      unsigned int sync_sample = stss->sample_numbers_[i];
      if(sync_sample >= end + 1)
        break;
      stss->sample_numbers_[entries] = sync_sample - start;
      ++entries;
    }
    stss->entries_ = entries;
  }

  // process sample sizes
  {
    struct stsz_t* stsz = trak->mdia_->minf_->stbl_->stsz_;
    if(stsz != NULL)
    {
      if(stsz->sample_size_ == 0)
      {
        unsigned int entries = 0;
        unsigned int i;
        for(i = start; i != end; ++i)
        {
          stsz->sample_sizes_[entries] = stsz->sample_sizes_[i];
          ++entries;
        }
      }
      stsz->entries_ = end - start;
    }
  }
}