⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_mp4_parser.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            if (ret == UMC_OK) {
                ret = Atom_Skip(dr, &leaf_atom);
            }
        }
        else if ( Compare_Atom(&leaf_atom, "stts") )
        {
            ret = Read_stts(dr, &(stbl->stts));
        }
        else if ( Compare_Atom(&leaf_atom, "stss") )
        {
            ret = Read_stss(dr, &(stbl->stss));
        }
        else if ( Compare_Atom(&leaf_atom, "stsc") )
        {
            ret = Read_stsc(dr, &(stbl->stsc));
        }
        else if ( Compare_Atom(&leaf_atom, "stsz") )
        {
            ret = Read_stsz(dr, &(stbl->stsz));
        }
        else if ( Compare_Atom(&leaf_atom, "stco") )
        {
            ret = Read_stco(dr, &(stbl->stco));
        }
        else if ( Compare_Atom(&leaf_atom, "co64") )
        {
            ret = Read_co64(dr, &(stbl->co64));
        }
        else if ( Compare_Atom(&leaf_atom, "ctts") )
        {
            ret = Read_ctts(dr, &(stbl->ctts));
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    } while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    return ret;
}

// CO64 Box
// The chunk offset table gives the index of each chunk into the containing file. Use of 64-bit offsets.
//
Status MP4Splitter::Read_co64(DataReader *dr, T_co64_data *co64)
{
    Status ret = UMC_OK;
    unsigned int i;

    dr->Get8u(&co64->version);
    co64->flags = Get_24(dr);
    dr->Get32uSwap(&co64->total_entries);
    co64->table = (T_co64_table_data*)ippsMalloc_8u(sizeof(T_co64_table_data) * co64->total_entries);

    // Check memory allocation
    if (NULL == co64->table) {
        return ret;
    }

    // Zeroed allocated table

    memset(co64->table,  0, sizeof(T_co64_table_data) * co64->total_entries);


    for ( i = 0; i < co64->total_entries; i++ )
    {
        dr->Get64uSwap(&co64->table[i].offset);
    }

    return ret;
}

// CTTS Box
// This box provides the offset between decoding time and composition time.
//
Status MP4Splitter::Read_ctts(DataReader *dr, T_ctts_data *ctts)
{
    Status ret = UMC_OK;
    unsigned int i;

    dr->Get8u(&ctts->version);
    ctts->flags = Get_24(dr);
    dr->Get32uSwap(&ctts->total_entries);
    ctts->table = (T_ctts_table_data*)ippsMalloc_8u(sizeof(T_ctts_table_data) * ctts->total_entries);

    // Check memory allocation
    if (NULL == ctts->table) {
        return ret;
    }

    // Zeroed allocated table

    memset(ctts->table,  0, sizeof(T_ctts_table_data) * ctts->total_entries);

    for ( i = 0; i < ctts->total_entries; i++ )
    {
        dr->Get32uSwap(&ctts->table[i].sample_count);
        dr->Get32uSwap(&ctts->table[i].sample_offset);
    }

    return ret;
}

// STCO Box
// The chunk offset table gives the index of each chunk into the containing file. Use of 32-bit offsets.
//
Status MP4Splitter::Read_stco(DataReader *dr, T_stco_data *stco)
{
    Status ret = UMC_OK;
    unsigned int i;

    dr->Get8u(&stco->version);
    stco->flags = Get_24(dr);
    dr->Get32uSwap(&stco->total_entries);
    stco->table = (T_stco_table_data*)ippsMalloc_8u(sizeof(T_stco_table_data) * stco->total_entries);

    // Check memory allocation
    if (NULL == stco->table) {
        return ret;
    }

    // Zeroed allocated table

    memset(stco->table,  0, sizeof(T_stco_table_data) * stco->total_entries);

    for ( i = 0; i < stco->total_entries; i++ )
    {
        dr->Get32uSwap(&stco->table[i].offset);
    }

    return ret;
}

// STSZ Box
// This box contains the sample count and a table giving the size in bytes of each sample. This allows the media
// data itself to be unframed. The total number of samples in the media is always indicated in the sample count.
//
Status MP4Splitter::Read_stsz(DataReader *dr, T_stsz_data *stsz)
{
    Status ret = UMC_OK;
    unsigned int i;

    dr->Get8u(&stsz->version);
    stsz->flags = Get_24(dr);
    dr->Get32uSwap(&stsz->sample_size);
    dr->Get32uSwap(&stsz->total_entries);
    stsz->max_sample_size = stsz->sample_size;  // to calculate buffer size
    if (!stsz->sample_size) {
      stsz->table = (T_stsz_table_data*)ippsMalloc_8u(sizeof(T_stsz_table_data) * stsz->total_entries);

      // Check memory allocation
      if (NULL == stsz->table) {
          return ret;
      }

      // Zeroed allocated table

      memset(stsz->table,  0, sizeof(T_stsz_table_data) * stsz->total_entries);

      for (i = 0; i < stsz->total_entries; i++) {
        dr->Get32uSwap(&stsz->table[i].size);
        if (stsz->table[i].size > stsz->max_sample_size) {
            stsz->max_sample_size = stsz->table[i].size;
        }
      }
    }

    return ret;
}

// STSC Box
// Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the samples
// within a chunk can have different sizes. This table can be used to find the chunk that contains a sample, its
// position, and the associated sample description.
//
Status MP4Splitter::Read_stsc(DataReader *dr, T_stsc_data *stsc)
{
    Status ret = UMC_OK;
    unsigned int i;
    unsigned int sample = 0;

    dr->Get8u(&stsc->version);
    stsc->flags = Get_24(dr);
    dr->Get32uSwap(&stsc->total_entries);
/////    stsc->entries_allocated = stsc->total_entries;
    stsc->table = (T_stsc_table_data*)ippsMalloc_8u(sizeof(T_stsc_table_data) * stsc->total_entries);

    // Check memory allocation
    if (NULL == stsc->table) {
        return ret;
    }

    // Zeroed allocated table

    memset(stsc->table,  0, sizeof(T_stsc_table_data) * stsc->total_entries);

    for ( i = 0; i < stsc->total_entries; i++ )
    {
        dr->Get32uSwap(&stsc->table[i].chunk);
        dr->Get32uSwap(&stsc->table[i].samples);
        dr->Get32uSwap(&stsc->table[i].id);
    }
    for ( i = 0; i < stsc->total_entries; i++ )
    {
        stsc->table[i].first_sample = sample;
        if ( i < stsc->total_entries - 1 )
        {
            sample += (stsc->table[i+1].chunk - stsc->table[i].chunk) * stsc->table[i].samples;
        }
    }

    return ret;
}

// STTS Box
// This box contains a compact version of a table that allows indexing from decoding time to sample number.
//
Status MP4Splitter::Read_stts(DataReader *dr, T_stts_data *stts)
{
    Status ret = UMC_OK;
    unsigned int i;

    dr->Get8u(&stts->version);
    stts->flags = Get_24(dr);
    dr->Get32uSwap(&stts->total_entries);
    stts->table = (T_stts_table_data*)ippsMalloc_8u(sizeof(T_stts_table_data) * stts->total_entries);

    // Check memory allocation
    if (NULL == stts->table) {
        return ret;
    }

    // Zeroed allocated table

    memset(stts->table,  0, sizeof(T_stts_table_data) * stts->total_entries);

    for( i = 0; i < stts->total_entries; i++ )
    {
        dr->Get32uSwap(&stts->table[i].sample_count);
        dr->Get32uSwap(&stts->table[i].sample_duration);
    }

    return ret;
}

// STSS Box
// This box contains a sync (key, I-frame) sample map.
//
Ipp32s MP4Splitter::Read_stss(DataReader *dr, T_stss_data *stss)
{
    Status ret = UMC_OK;
    Ipp32u i;

    dr->Get8u(&stss->version);
    stss->flags = Get_24(dr);
    dr->Get32uSwap(&stss->total_entries);
    stss->table = (T_stss_table_data*)ippsMalloc_8u(sizeof(T_stss_table_data) * stss->total_entries);

    // Check memory allocation
    if (NULL == stss->table) {
        return ret;
    }

    // Zeroed allocated table

    memset(stss->table,  0, sizeof(T_stss_table_data) * stss->total_entries);

    for( i = 0; i < stss->total_entries; i++ )
    {
        dr->Get32uSwap(&stss->table[i].sample_number);
        UMC_CHECK_STATUS(ret)
    }

    return ret;
}
// STSD Box
// The sample description table gives detailed information about the coding type used, and any initialization
// information needed for that coding.
//
Status MP4Splitter::Read_stsd(DataReader *dr, T_minf_data *minf, T_stsd_data *stsd)
{
    Status ret = UMC_OK;
    unsigned int i;

    dr->Get8u(&stsd->version);
    stsd->flags = Get_24(dr);
    dr->Get32uSwap(&stsd->total_entries);
    stsd->table = (T_stsd_table_data*)ippsMalloc_8u(sizeof(T_stsd_table_data) * stsd->total_entries);

    // Check memory allocation
    if (NULL == stsd->table)
    {
        return ret;
    }

    // Zeroed allocated table
    memset(stsd->table,  0, sizeof(T_stsd_table_data) * stsd->total_entries);

    for ( i = 0; i < stsd->total_entries; i++ )
    {
        ret = Read_stsd_table(dr, minf, &(stsd->table[i]));
        UMC_CHECK_STATUS(ret)
    }

    return ret;
}

Status MP4Splitter::Read_samr_audio(DataReader *dr,
                                    T_stsd_table_data *table,
                                    T_atom_mp4 *parent_atom)
{
  Status ret;
  T_atom_mp4 leaf_atom;
  Ipp16u i;
  dr->MovePosition(16); // reserved
  dr->Get16uSwap(&i);
  dr->MovePosition(2); // reserved

  ret = Read_Atom(dr, &leaf_atom);
  UMC_CHECK_STATUS(ret)

  if (leaf_atom.type[0] == 'd' && leaf_atom.type[1] == 'a' &&
      leaf_atom.type[2] == 'm' && leaf_atom.type[3] =='r') {
    return Read_damr_audio(dr, table, &leaf_atom);
  }

  return ret;
}

Status MP4Splitter::Read_damr_audio(DataReader *dr,
                                    T_stsd_table_data *table,
                                    T_atom_mp4 *parent_atom)
{
  Ipp32u    temp;

  table->damr.decoderConfigLen = (Ipp32s)(parent_atom->size - 8);
  table->damr.decoderConfig = (Ipp8u*)(ippsMalloc_8u(table->damr.decoderConfigLen));

  // Check memory allocation
  if (NULL == table->damr.decoderConfig) {
    return UMC_OK;
  }

  // Zeroed allocated table
  memset(table->damr.decoderConfig,  0, table->damr.decoderConfigLen);

  temp = table->damr.decoderConfigLen;
  dr->GetData(table->damr.decoderConfig, (Ipp32u*) &temp);

  return UMC_OK;
}

Status MP4Splitter::Read_stsd_table(DataReader *dr, T_minf_data * /*minf*/, T_stsd_table_data *table)
{
    Status ret;
    T_atom_mp4 leaf_atom;

    ret = Read_Atom(dr, &leaf_atom);
    UMC_CHECK_STATUS(ret)

    table->is_protected = 0;
    table->format[0] = leaf_atom.type[0];
    table->format[1] = leaf_atom.type[1];
    table->format[2] = leaf_atom.type[2];
    table->format[3] = leaf_atom.type[3];
    dr->MovePosition(6); // RESERVED
    dr->Get16uSwap(&table->data_reference);
    if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='a' )
    {
        ret = Read_stsd_audio(dr, table, &leaf_atom);
    }
    if ( table->format[0]=='s'&& table->format[1]=='a'&& table->format[2]=='m'&& table->format[3]=='r' )
    {
        ret = Read_samr_audio(dr, table, &leaf_atom);
    }
    if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='v' )
    {
        ret = Read_stsd_video(dr, table, &leaf_atom);
    }
    if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='s' )
    {
        ret = Read_stsd_hint(dr, table, &leaf_atom);
    }

    if ( table->format[0]=='d' && table->format[1]=='r' && table->format[2]=='m' && table->format[3]=='s' )
    {
        ret = Read_stsd_drms(dr, table, &leaf_atom);
    }

    if ( table->format[0]=='s'&& table->format[1]=='2'&& table->format[2]=='6'&& table->format[3]=='3' )
    {
        ret = Read_h263_video(dr, table, &leaf_atom);
        table->esds.objectTypeID = 0xf2;
    }

    if ( table->format[0]=='a'&& table->format[1]=='v'&& table->format[2]=='c'&& table->format[3]=='1' )
    {
        ret = Read_h264_video(dr, table, &leaf_atom);
        table->esds.objectTypeID = 0xf1;
    }

    return ret;
}

Status MP4Splitter::Read_stsd_drms(UMC::DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
{
    Status ret = UMC_OK;
    unsigned short sample_rate;

    table->is_protected = 1;

    dr->MovePosition(8); // reserved

    dr->Get16uSwap(&table->channels);
    dr->Get16uSwap(&table->sample_size);

    dr->MovePosition(4); // reserved

    dr->Get16uSwap(&sample_rate);
    table->sample_rate = sample_rate;

    dr->MovePosition(2); // reserved

    while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK))
    {
        T_atom_mp4 leaf_atom;
        ret = Read_Atom(dr, &leaf_atom);
        UMC_CHECK_STATUS(ret)

        if (Compare_Atom(&leaf_atom, "esds"))
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -