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

📄 umc_mp4_parser.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2004-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_mp4_spl.h"
#include "umc_mp4_parser.h"

namespace UMC
{

Status MP4Splitter::Read_traf(DataReader *dr, T_traf *traf, T_atom_mp4 *atom)
{
    Status ret;
    T_atom_mp4    current_atom;

    traf->entry_count = 0;

    do
    {
        ret = Read_Atom(dr, &current_atom);
        UMC_CHECK_STATUS(ret)

        if (Compare_Atom(&current_atom, "tfhd"))
        {
            ret = Read_tfhd(dr, &traf->tfhd);
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &current_atom);
            UMC_CHECK_STATUS(ret)
        }

        if (Compare_Atom(&current_atom, "trun"))
        {
            if (!traf->trun[traf->entry_count])
            {
                traf->trun[traf->entry_count] = (T_trun*) (ippsMalloc_8u(sizeof(T_trun)));
                memset(traf->trun[traf->entry_count], 0, sizeof(T_trun));
            }
            ret = Read_trun(dr, traf->trun[traf->entry_count]);
            UMC_CHECK_STATUS(ret)
            traf->entry_count++;
            ret = Atom_Skip(dr, &current_atom);
        }
    } while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    if (traf->entry_count > traf->max_truns)
        traf->max_truns = traf->entry_count;

    return ret;
}
/*****

Status Read_traf(DataReader *dr, T_traf *traf, T_atom_mp4 *atom)
{
    Status ret;
    T_atom_mp4    current_atom;

    traf->entry_count = 0;

    do
    {
        ret = Read_Atom(m_pDataReader, &current_atom);
        UMC_CHECK_STATUS(ret)

        if (Compare_Atom(&current_atom, "tfhd"))
        {
            ret = Read_tfhd(m_pDataReader, &traf->tfhd);
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(m_pDataReader, &current_atom);
            UMC_CHECK_STATUS(ret)
        }

        if (Compare_Atom(&current_atom, "trun"))
        {
            if (!traf->trun[traf->entry_count])
            {
                traf->trun[traf->entry_count] = (T_trun*) (ippsMalloc_8u(sizeof(T_trun)));
                memset(traf->trun[traf->entry_count], 0, sizeof(T_trun));
            }
            ret = Read_trun(m_pDataReader, traf->trun[traf->entry_count]);
            UMC_CHECK_STATUS(ret)
            traf->entry_count++;
            ret = Atom_Skip(m_pDataReader, &current_atom);
        }
    } while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    if (traf->entry_count > traf->max_truns)
        traf->max_truns = traf->entry_count;

    return ret;
}
*/

Status MP4Splitter::Read_tfhd(DataReader *dr, T_tfhd *tfhd)
{
    dr->Get8u(&tfhd->version);
    tfhd->flags = Get_24(dr);
    dr->Get32uSwap(&tfhd->track_ID);

    if (tfhd->flags & 0x000001)
    {
        dr->Get64uSwap((Ipp64u*)&tfhd->base_data_offset);
    }
    else
    {
        tfhd->base_data_offset = 0;
    }

    if (tfhd->flags & 0x000002)
    {
        dr->Get32uSwap((Ipp32u*)&tfhd->sample_description_index);
    }
    else
    {
        tfhd->sample_description_index = 0;
    }

    if (tfhd->flags & 0x000008)
    {
        dr->Get32uSwap((Ipp32u*)&tfhd->default_sample_duration);
    }
    else
    {
        tfhd->default_sample_duration = 0;
    }

    if (tfhd->flags & 0x000010)
    {
        dr->Get32uSwap((Ipp32u*)&tfhd->default_sample_size);
    }
    else
    {
        tfhd->default_sample_size = 0;
    }

    if (tfhd->flags & 0x000020)
    {
        dr->Get32uSwap((Ipp32u*)&tfhd->default_sample_flags);
    }
    else
    {
        tfhd->default_sample_flags = 0;
    }

    return UMC_OK;
}

Status MP4Splitter::Read_trun(DataReader *dr, T_trun *trun)
{
    dr->Get8u(&trun->version);
    trun->flags = Get_24(dr);
    dr->Get32uSwap(&trun->sample_count);
    if (trun->flags & 0x000001)
    {
        dr->Get32uSwap((Ipp32u*)&trun->data_offset);
    }
    else
    {
        trun->data_offset = 0;
    }
    if (trun->flags & 0x000004)
    {
        dr->Get32uSwap((Ipp32u*)&trun->first_sample_flags);
    }
    else
    {
        trun->first_sample_flags = 0;
    }

    if (!trun->table_trun)
    {
        trun->table_trun = (T_trun_table_data*) (ippsMalloc_8u(sizeof(T_trun_table_data) * /*trun->sample_count*/40000));  // 40000 ~= number of entries in standard moof box
    }
    memset(trun->table_trun, 0, sizeof(T_trun_table_data) * /*trun->sample_count*/40000);
    return Read_trun_table(dr, trun, trun->table_trun);
    //return 0;
}

Status MP4Splitter::Read_trun_table(DataReader *dr, T_trun* trun, T_trun_table_data* table)
{
    for (unsigned int i = 0; i < trun->sample_count; i++)
    {
        if (trun->flags & 0x000100)
        {
            dr->Get32uSwap((Ipp32u*)&table[i].sample_duration);
        }

        if (trun->flags & 0x000200)
        {
            dr->Get32uSwap((Ipp32u*)&table[i].sample_size);
        }

        if (trun->flags & 0x000400)
        {
            dr->Get32uSwap((Ipp32u*)&table[i].sample_flags);
        }

        if (trun->flags & 0x000800)
        {
            dr->Get32uSwap((Ipp32u*)&table[i].sample_composition_time_offset);
        }
    }
    return 0;
}

Status MP4Splitter::Clear_moof(T_moof &moof)
{
  Ipp32u i, j;

  for (i = 0; i < moof.total_tracks; i++) {
    for (j = 0; j < moof.traf[i]->entry_count; j++) {
      UMC_FREE(moof.traf[i]->trun[j]->table_trun)
      UMC_FREE(moof.traf[i]->trun[j])
    }
    UMC_FREE(moof.traf[i])
  }

  return UMC_OK;
}

Status MP4Splitter::Read_moof(DataReader *dr, T_moof *moof, T_atom_mp4 *atom)
{
  Status     umcRes;
  T_atom_mp4 current_atom;

  moof->end = atom->end;
  moof->total_tracks = 0;

  do
  {
    umcRes = Read_Atom(dr, &current_atom);
    UMC_CHECK_STATUS(umcRes)

    if (Compare_Atom(&current_atom, "mfhd")) {
      umcRes = Read_mfhd(dr, &moof->mfhd);
      UMC_CHECK_STATUS(umcRes)
      umcRes = Atom_Skip(dr, &current_atom);
    } else if (Compare_Atom(&current_atom, "traf")) {
      if (!moof->traf[moof->total_tracks]) {
        moof->traf[moof->total_tracks] = (T_traf*)(ippsMalloc_8u(sizeof(T_traf)));
        memset(moof->traf[moof->total_tracks], 0, sizeof(T_traf));
      }
      umcRes = Read_traf(dr, moof->traf[moof->total_tracks], &current_atom);
      UMC_CHECK_STATUS(umcRes)

      umcRes = Atom_Skip(dr, &current_atom);
      UMC_CHECK_STATUS(umcRes)
      moof->total_tracks++;
    } else {
      return UMC_ERR_INVALID_STREAM;
    }

  } while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (umcRes == UMC_OK));

    return umcRes;
}
/*****

Status Read_moof(DataReader *dr, T_moof *moof, T_atom_mp4 *atom)
{
    Status ret;
    T_atom_mp4    current_atom;

    moof->end = atom->end;
    moof->total_tracks = 0;

    do
    {
        ret = Read_Atom(m_pDataReader, &current_atom);
        UMC_CHECK_STATUS(ret)

        if (Compare_Atom(&current_atom, "mfhd"))
        {
            ret = Read_mfhd(m_pDataReader, &moof->mfhd);
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(m_pDataReader, &current_atom);
        }
        else if (Compare_Atom(&current_atom, "traf"))
        {
            if (!moof->traf[moof->total_tracks])
            {
                moof->traf[moof->total_tracks] = (T_traf*) (ippsMalloc_8u(sizeof(T_traf)));
                memset(moof->traf[moof->total_tracks], 0, sizeof(T_traf));
            }
            ret = Read_traf(m_pDataReader, moof->traf[moof->total_tracks], &current_atom);
            UMC_CHECK_STATUS(ret)

            ret = Atom_Skip(m_pDataReader, &current_atom);
            UMC_CHECK_STATUS(ret)
            moof->total_tracks++;
        }
        else
        {
            return UMC_ERR_INVALID_STREAM;
        }

    }while((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    return ret;
}
*/

long MP4Splitter::Get_24(DataReader *dr)
{
    unsigned int    result = 0;
    unsigned int    a, b, c;
    unsigned int    len;
    char            data[3];

    len = 3;
    dr->GetData(data, (Ipp32u*) &len);
    a = (unsigned char)data[0];
    b = (unsigned char)data[1];
    c = (unsigned char)data[2];
    result = (a<<16) + (b<<8) + c;
    return (long)result;
}

Ipp32s MP4Splitter::Read_mp4_descr_length(DataReader *dr)
{
    unsigned char    b;
    Ipp8u            numBytes = 0;
    Ipp32s           length = 0;

    do
    {
        dr->Get8u(&b);
        numBytes++;
        length = (length << 7) | (b & 0x7F);
    } while ((b & 0x80) && numBytes < 4);

    return length;
}

/*****
Ipp32s Get_mp4_descr_length(DataReader *dr)
{
    unsigned char    b;
    Ipp8u            numBytes = 0;
    Ipp32s           length = 0;

    do
    {
        dr->Get8u(&b);
        numBytes++;
        length = (length << 7) | (b & 0x7F);
    } while ((b & 0x80) && numBytes < 4);

    return length;
}
*/

Status MP4Splitter::Atom_Skip(DataReader *dr, T_atom_mp4 *atom)
{
#ifndef UMC_MF
  dr->SetPosition((Ipp64u)0);
  dr->StartReadingAfterReposition();
  return dr->MovePosition((int)atom->end);
#else
  return dr->SetPosition(atom->end);
#endif
}

Status MP4Splitter::Compare_Atom(T_atom_mp4 *atom, char *type)
{
    if ( atom->type[0] == type[0] &&
        atom->type[1] == type[1] &&
        atom->type[2] == type[2] &&
        atom->type[3] == type[3] )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

Status MP4Splitter::Read_Atom(DataReader *dr, T_atom_mp4 *atom)
{
    Status ret;
    unsigned int len;
    unsigned int size = 0;
    atom->start = dr->GetPosition();
    dr->Get32uSwap(&size);
    atom->is_large_size = (size == 1);
    len = 4;
    ret = dr->GetData(&atom->type, (Ipp32u*) &len);
    if (ret != UMC_OK)
    {
        return UMC_ERR_FAILED;
    }

    if (size == 1)
    {
        ret = dr->Get64uSwap(&atom->size);
        if (ret != UMC_OK)
        {
            return UMC_ERR_FAILED;
        }
    }
    else
    {
        atom->size = size;
    }

    atom->end = atom->start + atom->size;

    if (atom->type[0] == 'u' &&
        atom->type[1] == 'u' &&
        atom->type[2] == 'i' &&
        atom->type[3] == 'd')
    {
        char userType[128];
        len = 128;
        ret = dr->GetData(userType, (Ipp32u*)&len);
    }

    return ret;
}

T_trak_data* MP4Splitter::Add_trak(T_moov *moov)
{
    if ( moov->total_tracks < MAXTRACKS )
    {
        moov->trak[moov->total_tracks] = (T_trak_data*) (ippsMalloc_8u(sizeof(T_trak_data)));
        if (moov->trak[moov->total_tracks]) {

⌨️ 快捷键说明

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