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

📄 umc_mp4_parser.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            ret = Read_esds(dr, &(table->esds));
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &leaf_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    }

    return ret;
} // int Read_stsd_drms(UMC::DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
// STSD_HINT
// For hint tracks, the sample description contains appropriate declarative data for the streaming protocol being
// used, and the format of the hint track. The definition of the sample description is specific to the protocol.
//
Status MP4Splitter::Read_stsd_hint(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
{
    Status ret = UMC_OK;

    //dr->MovePosition(16); // 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") )
        {
            ret = Read_esds(dr, &(table->esds));
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &leaf_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    }

    return ret;
}

// STSD_VIDEO
// For video tracks, a VisualSampleEntry is used.
//
Status MP4Splitter::Read_stsd_video(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
{
    Status ret = UMC_OK;

    dr->MovePosition(2 + 2 + 3*4);
    table->width = 0;
    table->height = 0;
    dr->Get16uSwap(&table->width);
    dr->Get16uSwap(&table->height);
    dr->Get32uSwap(&table->dpi_horizontal);
    dr->Get32uSwap(&table->dpi_vertical);
    dr->MovePosition(4 + 2 + 32 + 2 + 2);

    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"))
        {
            ret = Read_esds(dr, &(table->esds));
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &leaf_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    }

    return ret;
    //return 0;
}

Status MP4Splitter::Read_h263_video(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
{
    dr->MovePosition(16);

    table->width = 0;
    table->height = 0;

    dr->Get16uSwap(&table->width);
    dr->Get16uSwap(&table->height);

    dr->MovePosition(39);
    dr->MovePosition(8);

    return UMC_OK;
}

void MP4Splitter::SetH264FrameIntraSize(Ipp8u* decoderConfig)
{
    Ipp8u *p = decoderConfig;
    p += 4;
    m_nH264FrameIntraSize = *p;
    m_nH264FrameIntraSize <<= 6;
    m_nH264FrameIntraSize >>= 6; // remove reserved bits
    m_nH264FrameIntraSize++;
    return;
};

Ipp32s MP4Splitter::Read_h264_video(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
{
    Status ret = UMC_OK;

    dr->MovePosition(16);

    table->width = 0;
    table->height = 0;

    dr->Get16uSwap(&table->width);
    dr->Get16uSwap(&table->height);

    dr->MovePosition(50);

    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, "avcC"))
        {
            Ipp32u    temp;

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

            // Check memory allocation
            if (NULL == table->avcC.decoderConfig && table->avcC.decoderConfigLen > 0)
            {
                return UMC_ERR_FAILED;
            }
            // Zeroed allocated table
            memset(table->avcC.decoderConfig,  0, table->avcC.decoderConfigLen);

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

            if (temp > 4)
                SetH264FrameIntraSize(table->avcC.decoderConfig);
 //*****               SetH264FrameIntraSize(table->avcC.decoderConfig, m_nH264FrameIntraSize);

            ret = Atom_Skip(dr, &leaf_atom);
        }
        else if (Compare_Atom(&leaf_atom, "btrt"))
        {
            dr->Get32uSwap((Ipp32u*)&table->esds.bufferSizeDB);
            dr->Get32uSwap(&table->esds.maxBitrate);
            dr->Get32uSwap(&table->esds.avgBitrate);
            ret = Atom_Skip(dr, &leaf_atom);
        }
        else if ( Compare_Atom(&leaf_atom, "m4ds") )
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    }

    return ret;
}

Status MP4Splitter::Read_stsd_audio(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom)
{
    Status ret = UMC_OK;

    dr->MovePosition(8); // RESERVED
    dr->Get16uSwap(&table->channels);
    dr->Get16uSwap(&table->sample_size);
    dr->MovePosition(4); // RESERVED
    dr->Get32uSwap(&table->sample_rate);
    table->sample_rate = table->sample_rate >> 16;

    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"))
        {
            ret = Read_esds(dr, &(table->esds));
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &leaf_atom);
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
        }
    }

    return ret;
}

Status MP4Splitter::Read_esds(DataReader *dr, T_esds_data *esds)
{
    unsigned char tag;
    unsigned char temp2 = 0;
    int len;
    unsigned int temp;

    dr->Get8u(&esds->version);
    esds->flags = Get_24(dr);

    esds->decoderConfigLen = 0;
    /* get and verify ES_DescrTag */
    dr->Get8u(&tag);
    if ( tag == 0x03 )
    {
        len = Read_mp4_descr_length(dr);
        dr->Get16uSwap(&esds->es_ID);
        dr->Get8u(&temp2);
        esds->streamDependenceFlag = temp2 & (1 << 7) ? 1 : 0;
        esds->urlflag = temp2 & (1 << 6) ? 1 : 0;
        esds->ocrflag = temp2 & (1 << 5) ? 1 : 0;
        esds->streamPriority = temp2 & 0x1f;
        len -= 3;
        while ( len > 0 )
        {
            dr->Get8u(&tag);
            len -= 1;
            switch ( tag )
            {
                case 0x04: // verify DecoderConfigDescrTag
                {
                    Read_mp4_descr_length(dr);
                    dr->Get8u(&esds->objectTypeID);
                    dr->Get8u(&esds->streamType);    // 3 - video, 4 - graphic, 5 - audio
                    esds->bufferSizeDB = Get_24(dr);
                    dr->Get32uSwap(&esds->maxBitrate);
                    dr->Get32uSwap(&esds->avgBitrate);
                    len -= 17;
                    if (0 == len) break;

                    dr->Get8u(&tag);

                    if ( tag == 0x05 )
                    {
                        esds->decoderConfigLen = Read_mp4_descr_length(dr);
                        if ( esds->decoderConfigLen )
                        {
                            esds->decoderConfig = (Ipp8u*)(ippsMalloc_8u(esds->decoderConfigLen));

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

                            // Zeroed allocated table

                            memset(esds->decoderConfig,  0, esds->decoderConfigLen);

                            esds->start = dr->GetPosition();
                            temp = esds->decoderConfigLen;
                            dr->GetData(esds->decoderConfig, (Ipp32u*) &temp);
                            len -= 4 + temp;
                        }
                        else
                        {
                            esds->decoderConfigLen = 0;
                            len -= 4;
                        }
                    }
                    break;
                }
                case 0x06: // verify DecSpecificInfoTag
                {
                    temp = Read_mp4_descr_length(dr);
                    dr->MovePosition(temp);    // skip SL tag
                    len -= 4 + temp;
                    break;
                }
            } // switch tag
        } // while
    } // if (tag)
    else
    {
        return UMC_OK;
    }

    return UMC_OK;
}

// DINF Box
// The data information box contains objects that declare the location of the media information in a track.
//
Status MP4Splitter::Read_dinf(DataReader *dr, T_dinf_data *dinf, T_atom_mp4 *dinf_atom)
{
    Status ret;
    T_atom_mp4 leaf_atom;

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

        if(Compare_Atom(&leaf_atom, "dref"))
        {
            ret = Read_dref(dr, &(dinf->dref));
            UMC_CHECK_STATUS(ret)
        }
        else
        {
            ret = Atom_Skip(dr, &leaf_atom);
            UMC_CHECK_STATUS(ret)
        }
    } while ((dr->GetPosition() < dinf_atom->end) && (dr->GetPosition() != 0) && (ret == UMC_OK));

    return ret;
}


// DREF Box
// The data reference object contains a table of data references (normally URLs) that declare the location(s) of
// the media data used within the presentation.
//
Status MP4Splitter::Read_dref(DataReader *dr, T_dref_data *dref)
{
    Status ret = UMC_OK;
    unsigned int i;

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

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

    // Zeroed allocated table
    memset(dref->table,  0, sizeof(T_dref_table_data) * dref->total_entries);

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

    return ret;
}

Status MP4Splitter::Read_dref_table(DataReader *dr, T_dref_table_data *table)
{
    Status ret = UMC_OK;
    unsigned int len;

    dr->Get32uSwap(&table->size);
    len = 4;
    dr->GetData(table->type, (Ipp32u*) &len);
    dr->Get8u(&table->version);
    table->flags = Get_24(dr);
    table->data_reference = (char*)ippsMalloc_8u(table->size);

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

    // Zeroed allocated table
    memset(table->data_reference,  0, table->size);

    len = table->size - 12;
    if ( table->size > 12 )
    {
        dr->GetData(table->data_reference, (Ipp32u*) &len);
    }
    table->data_reference[table->size - 12] = 0;

    return ret;
}

Status MP4Splitter::Read_mvex(DataReader *dr, T_mvex_data *mvex, T_atom_mp4 *atom)
{
    Status ret;
    T_atom_mp4    current_atom;

    mvex->total_tracks = 0;

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

        if (Compare_Atom(&current_atom, "trex"))
        {
            mvex->trex[mvex->total_tracks] = (T_trex_data*) (ippsMalloc_8u(sizeof(T_trex_data)));
            ret = Read_trex(dr, (mvex->trex[mvex->total_tracks]));
            UMC_CHECK_STATUS(ret)
            ret = Atom_Skip(dr, &current_atom);
            mvex->total_tracks++;
        }

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

    return ret;
}

Status MP4Splitter::Read_trex(DataReader *dr, T_trex_data *trex)
{
    dr->Get8u(&trex->version);
    trex->flags = Get_24(dr);
    dr->Get32uSwap(&trex->track_ID);
    dr->Get32uSwap(&trex->default_sample_description_index);
    dr->Get32uSwap(&trex->default_sample_duration);
    dr->Get32uSwap(&trex->default_sample_size);
    dr->Get32uSwap(&trex->default_sample_flags);

    return UMC_OK;
}

Status MP4Splitter::Read_mfhd(DataReader *dr, T_mfhd *mfhd)
{
  dr->Get8u(&mfhd->version);
  mfhd->flags = Get_24(dr);
  dr->Get32uSwap(&mfhd->sequence_number);

  return UMC_OK;
}

} // namespace UMC

⌨️ 快捷键说明

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