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

📄 umc_mp4_parser.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:

            memset(moov->trak[moov->total_tracks],  0, sizeof(T_trak_data));
            moov->total_tracks++;
        } else {
            return 0;
        }
    }
    else
    {
        return 0;
    }
    return moov->trak[moov->total_tracks - 1];
}

// MOOV Box
// The metadata for a presentation is stored in the single Movie Box which occurs at the top-level of a file.
//
Status MP4Splitter::Read_moov(DataReader *dr, T_moov *moov, T_atom_mp4 *atom)
{
    Status ret;
    T_atom_mp4    current_atom;

    moov->total_tracks = 0;
    do
    {
        ret = Read_Atom(dr, &current_atom);
        UMC_CHECK_STATUS(ret)

        if (Compare_Atom(&current_atom, "mvhd"))
        {
            ret = Read_mvhd(dr, &(moov->mvhd));
        }
        else if (Compare_Atom(&current_atom, "iods"))
        {
            ret = Read_iods(dr, &(moov->iods));
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &current_atom);
        }
        else if (Compare_Atom(&current_atom, "mvex"))
        {
            ret = Read_mvex(dr, &moov->mvex, &current_atom);
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &current_atom);
        }
        /*else if ( Compare_Atom(&current_atom, "clip") )
        {
            Atom_Skip(dr, &current_atom);
        }*/
        else if (Compare_Atom(&current_atom, "trak"))
        {
            T_trak_data *trak = Add_trak(moov);
            if (trak == 0)
            {
                return UMC_ERR_FAILED;
            }
            ret = Read_trak(dr, trak, &current_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &current_atom);
        }
    } while ((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    return ret;
}

// MVHD Box
// This box defines overall information which is media-independent, and relevant to the entire presentation
// considered as a whole.
//
Status MP4Splitter::Read_mvhd(DataReader *dr, T_mvhd_data *mvhd)
{
    Status ret = UMC_OK;
    unsigned int temp;

    dr->Get8u(&mvhd->version);
    mvhd->flags = Get_24(dr);
    if ( mvhd->version )
    {
        dr->Get64uSwap(&mvhd->creation_time);
        dr->Get64uSwap(&mvhd->modification_time);
        dr->Get32uSwap(&mvhd->time_scale);
        dr->Get64uSwap(&mvhd->duration);
    }
    else
    {
        dr->Get32uSwap(&temp);
        mvhd->creation_time = temp;
        dr->Get32uSwap(&temp);
        mvhd->modification_time = temp;
        dr->Get32uSwap(&mvhd->time_scale);
        dr->Get32uSwap(&temp);
        mvhd->duration = temp;
    }
    dr->MovePosition((9 + 6) * 4 + 10 + 2 + 4); // RESERVED
    dr->Get32uSwap(&mvhd->next_track_id);

    return ret;
}

Status MP4Splitter::Read_iods(DataReader *dr, T_iods_data *iods)
{
    Status ret = UMC_OK;
    unsigned char tag;

    dr->Get8u(&iods->version);
    iods->flags = Get_24(dr );
    dr->Get8u(&tag);
//****    Get_mp4_descr_length(dr);    // skip length
    Read_mp4_descr_length(dr);    // skip length
    // skip ODID, ODProfile, sceneProfile
    dr->Get16uSwap(&iods->objectDescriptorID); // ODID (16 bit ?)
    dr->Get8u(&iods->OD_profileAndLevel); // ODProfile
    dr->Get8u(&iods->scene_profileAndLevel); // sceneProfile
    dr->Get8u(&iods->audioProfileId);
    dr->Get8u(&iods->videoProfileId);
    dr->Get8u(&iods->graphics_profileAndLevel);
    return ret;
}

// TRAK Box
// This is a container box for a single track of a presentation. A presentation consists of one or more tracks.
// Each track is independent of the other tracks in the presentation and carries its own temporal and spatial
// information. Each track will contain its associated Media Box.
//
Status MP4Splitter::Read_trak(DataReader *dr, T_trak_data *trak, T_atom_mp4 *trak_atom)
{
    Status ret;
    T_atom_mp4 leaf_atom;

    trak->tref.dpnd.idTrak = 0;

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

        if (Compare_Atom(&leaf_atom, "tkhd"))
        {
            ret = Read_tkhd(dr, &(trak->tkhd));
        }
        else if (Compare_Atom(&leaf_atom, "mdia"))
        {
            ret = Read_mdia(dr, &(trak->mdia), &leaf_atom);
        }
        else if ( Compare_Atom(&leaf_atom, "tref") )
        {
            ret = Read_tref(dr, &(trak->tref), &leaf_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    } while ((dr->GetPosition() < trak_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    return ret;
}

// TREF Box
// This box provides a reference from the containing track to another track in the presentation. These references
// are typed.
//
Status MP4Splitter::Read_tref(DataReader *dr, T_tref_data *tref, T_atom_mp4 *atom)
{
    Status ret;
    T_atom_mp4 leaf_atom;

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

        if (Compare_Atom(&leaf_atom, "dpnd"))
        {
            ret = Read_dpnd(dr, &(tref->dpnd));
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    } while ((dr->GetPosition() < atom->end) && (dr->GetPosition() != 0)  && (ret == UMC_OK));

    return ret;
}


Status MP4Splitter::Read_dpnd(DataReader *dr, T_dpnd_data *dpnd)
{
    dr->Get32uSwap(&dpnd->idTrak);
    return UMC_OK;
}

// TKHD Box
// This box specifies the characteristics of a single track.
//
Status MP4Splitter::Read_tkhd(DataReader *dr, T_tkhd_data *tkhd)
{
    Status ret = UMC_OK;
    unsigned int temp;

    dr->Get8u(&tkhd->version);
    tkhd->flags = Get_24(dr);
    if ( tkhd->version )
    {
        dr->Get64uSwap(&tkhd->creation_time);
        dr->Get64uSwap(&tkhd->modification_time);
        dr->Get32uSwap(&tkhd->track_id);
        dr->MovePosition(4); //RESERVED
        dr->Get64uSwap(&tkhd->duration);
    }
    else
    {
        dr->Get32uSwap(&temp);
        tkhd->creation_time = temp;
        dr->Get32uSwap(&temp);
        tkhd->modification_time = temp;
        dr->Get32uSwap(&tkhd->track_id);
        dr->MovePosition(4); //RESERVED
        dr->Get32uSwap(&temp);
        tkhd->duration = temp;
    }
    dr->MovePosition(16 + 9 * 4); //RESERVED
    dr->Get32uSwap(&temp);
    tkhd->track_width = (float)(temp >> 16);
    dr->Get32uSwap(&temp);
    tkhd->track_height = (float)(temp >> 16);

    return ret;
}

// MDIA
// The media declaration container contains all the objects that declare information about the media data within a
// track.
//
Status MP4Splitter::Read_mdia(DataReader *dr, T_mdia_data *mdia, T_atom_mp4 *trak_atom)
{
    Status ret;
    T_atom_mp4 leaf_atom;

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

        if (Compare_Atom(&leaf_atom, "mdhd"))
        {
            ret = Read_mdhd(dr, &(mdia->mdhd));
        }
        else if (Compare_Atom(&leaf_atom, "hdlr"))
        {
            ret = Read_hdlr(dr, &(mdia->hdlr));
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &leaf_atom);
        }
        else if (Compare_Atom(&leaf_atom, "minf"))
        {
            ret = Read_minf(dr, &(mdia->minf), &leaf_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    } while ((dr->GetPosition() < trak_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    return ret;
}

// HDLR Box
// This box within a Media Box declares the process by which the media-data in the track is presented, and thus,
// the nature of the media in a track. For example, a video track would be handled by a video handler.
//
Status MP4Splitter::Read_hdlr(DataReader *dr, T_hdlr_data *hdlr)
{
    Status ret = UMC_OK;
    unsigned int len;

    dr->Get8u(&hdlr->version);
    hdlr->flags = Get_24(dr);
    dr->MovePosition(4); // RESERVED
    len = 4;
    dr->GetData(hdlr->component_type, (Ipp32u*) &len);
    dr->MovePosition(12); // RESERVED

    return ret;
}

// MDHD Box
// The media header declares overall information that is media-independent, and relevant to characteristics of
// the media in a track.
//
Status MP4Splitter::Read_mdhd(DataReader *dr, T_mdhd_data *mdhd)
{
    Status ret = UMC_OK;
    unsigned int temp;

    dr->Get8u(&mdhd->version);
    mdhd->flags = Get_24(dr);
    if ( mdhd->version )
    {
        dr->Get64uSwap(&mdhd->creation_time);
        dr->Get64uSwap(&mdhd->modification_time);
        dr->Get32uSwap(&mdhd->time_scale);
        dr->Get64uSwap(&mdhd->duration);
    }
    else
    {
        dr->Get32uSwap(&temp);
        mdhd->creation_time = temp;
        dr->Get32uSwap(&temp);
        mdhd->modification_time = temp;
        dr->Get32uSwap(&mdhd->time_scale);
        dr->Get32uSwap(&temp);
        mdhd->duration = temp;
    }
    dr->Get16uSwap(&mdhd->language);
    dr->Get16uSwap(&mdhd->quality);    // RESERVED

    return ret;
}

// MINF Box
// This box contains all the objects that declare characteristic information of the media in the track.
//
Status MP4Splitter::Read_minf(DataReader *dr, T_minf_data *minf, T_atom_mp4 *parent_atom)
{
    Status ret;
    T_atom_mp4 leaf_atom;

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

        if (Compare_Atom(&leaf_atom, "vmhd"))
        {
            minf->is_video = 1;
            ret = Read_vmhd(dr, &(minf->vmhd));
        }
        else if (Compare_Atom(&leaf_atom, "smhd"))
        {
            minf->is_audio = 1;
            ret = Read_smhd(dr, &(minf->smhd));
        }
        else if (Compare_Atom(&leaf_atom, "hmhd"))
        {
            minf->is_hint = 1;
            ret = Read_hmhd(dr, &(minf->hmhd));
        }
        else if (Compare_Atom(&leaf_atom, "dinf"))
        {
            ret = Read_dinf(dr, &(minf->dinf), &leaf_atom);
        }
        else if (Compare_Atom(&leaf_atom, "stbl"))
        {
            ret = Read_stbl(dr, minf, &(minf->stbl), &leaf_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    } while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    return ret;
}

// HMHD Box
// The hint media header contains general information, independent of the protocol, for hint tracks.
//
Status MP4Splitter::Read_hmhd(DataReader *dr, T_hmhd_data *hmhd)
{
    Status ret = UMC_OK;

    dr->Get8u(&hmhd->version);
    hmhd->flags = Get_24(dr);
    dr->Get16uSwap(&hmhd->maxPDUsize);
    dr->Get16uSwap(&hmhd->avgPDUsize);
    dr->Get32uSwap(&hmhd->maxbitrate);
    dr->Get32uSwap(&hmhd->avgbitrate);
    dr->Get32uSwap(&hmhd->slidingavgbitrate);

    return ret;
}

// VMHD Box
// The video media header contains general presentation information, independent of the coding, for video
// media.
//
Status MP4Splitter::Read_vmhd(DataReader *dr, T_vmhd_data *vmhd)
{
    Status ret = UMC_OK;

    dr->Get8u(&vmhd->version);
    vmhd->flags = Get_24(dr);
    dr->MovePosition(8);    // RESERVED

    return ret;
}

// SMHD Box
// The sound media header contains general presentation information, independent of the coding, for audio
// media. This header is used for all tracks containing audio.
//
Status MP4Splitter::Read_smhd(DataReader *dr, T_smhd_data *smhd)
{
    Status ret = UMC_OK;

    dr->Get8u(&smhd->version);
    smhd->flags = Get_24(dr);
    dr->MovePosition(4); // RESERVED

    return ret;
}

// STBL Box
// The sample table contains all the time and data indexing of the media samples in a track. Using the tables
// here, it is possible to locate samples in time, determine their type (e.g. I-frame or not), and determine their
// size, container, and offset into that container.
//
Status MP4Splitter::Read_stbl(DataReader *dr, T_minf_data *minf, T_stbl_data *stbl, T_atom_mp4 *parent_atom)
{
    Status ret;
    T_atom_mp4 leaf_atom;

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

        if (Compare_Atom(&leaf_atom, "stsd"))
        {
            ret = Read_stsd(dr, minf, &(stbl->stsd));

⌨️ 快捷键说明

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