📄 umc_mp4_parser.cpp
字号:
int SplitterMP4::Read_stsc(DataReader *dr, T_stsc_data *stsc){ unsigned int i; unsigned int sample = 0; dr->GetByte(&stsc->version); stsc->flags = Get_24(dr); dr->GetUInt(&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 0; } // Zeroed allocated table memset(stsc->table, 0, sizeof(T_stsc_table_data) * stsc->total_entries); for ( i = 0; i < stsc->total_entries; i++ ) { dr->GetUInt(&stsc->table[i].chunk); dr->GetUInt(&stsc->table[i].samples); dr->GetUInt(&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 0;}// STTS Box// This box contains a compact version of a table that allows indexing from decoding time to sample number.//int SplitterMP4::Read_stts(DataReader *dr, T_stts_data *stts){ unsigned int i; dr->GetByte(&stts->version); stts->flags = Get_24(dr); dr->GetUInt(&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 0; } // Zeroed allocated table memset(stts->table, 0, sizeof(T_stts_table_data) * stts->total_entries); for( i = 0; i < stts->total_entries; i++ ) { dr->GetUInt(&stts->table[i].sample_count); dr->GetUInt(&stts->table[i].sample_duration); } return 0;}// STSD Box// The sample description table gives detailed information about the coding type used, and any initialization// information needed for that coding.//int SplitterMP4::Read_stsd(DataReader *dr, T_minf_data *minf, T_stsd_data *stsd){ unsigned int i; dr->GetByte(&stsd->version); stsd->flags = Get_24(dr); dr->GetUInt(&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 0; } // Zeroed allocated table memset(stsd->table, 0, sizeof(T_stsd_table_data) * stsd->total_entries); for ( i = 0; i < stsd->total_entries; i++ ) { Read_stsd_table(dr, minf, &(stsd->table[i])); } return 0;}int SplitterMP4::Read_stsd_table(DataReader *dr, T_minf_data * /*minf*/, T_stsd_table_data *table){ T_atom_mp4 leaf_atom; Read_Atom(dr, &leaf_atom); 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->GetShort(&table->data_reference); if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='a' ) { Read_stsd_audio(dr, table, &leaf_atom); } if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='v' ) { Read_stsd_video(dr, table, &leaf_atom); } if ( table->format[0]=='m'&& table->format[1]=='p'&& table->format[2]=='4'&& table->format[3]=='s' ) { Read_stsd_hint(dr, table, &leaf_atom); } return 0;}// 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.//int SplitterMP4::Read_stsd_hint(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom){ //dr->MovePosition(16); // RESERVED while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) ) { T_atom_mp4 leaf_atom; Read_Atom(dr, &leaf_atom); if ( Compare_Atom(&leaf_atom, "esds") ) { Read_esds(dr, &(table->esds)); Atom_Skip(dr, &leaf_atom); } else { Atom_Skip(dr, &leaf_atom); } } return 0;}// STSD_VIDEO// For video tracks, a VisualSampleEntry is used.//int SplitterMP4::Read_stsd_video(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom){ dr->MovePosition(2 + 2 + 3*4); table->width = 0; table->height = 0; dr->GetShort(&table->width); dr->GetShort(&table->height); dr->GetUInt(&table->dpi_horizontal); dr->GetUInt(&table->dpi_vertical); dr->MovePosition(4 + 2 + 32 + 2 + 2); while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) ) { T_atom_mp4 leaf_atom; Read_Atom(dr, &leaf_atom); if ( Compare_Atom(&leaf_atom, "esds") ) { Read_esds(dr, &(table->esds)); Atom_Skip(dr, &leaf_atom); } else { Atom_Skip(dr, &leaf_atom); } } return 0;}// STSD_AUDIO// For audio tracks, an AudioSampleEntry.//int SplitterMP4::Read_stsd_audio(DataReader *dr, T_stsd_table_data *table, T_atom_mp4 *parent_atom){ dr->MovePosition(8); // RESERVED dr->GetShort(&table->channels); dr->GetShort(&table->sample_size); dr->MovePosition(4); // RESERVED dr->GetUInt(&table->sample_rate); table->sample_rate = table->sample_rate >> 16; while ( (dr->GetPosition() < parent_atom->end) && (dr->GetPosition() != 0) ) { T_atom_mp4 leaf_atom; Read_Atom(dr, &leaf_atom); if ( Compare_Atom(&leaf_atom, "esds") ) { Read_esds(dr, &(table->esds)); Atom_Skip(dr, &leaf_atom); } else { Atom_Skip(dr, &leaf_atom); } } return 0;}int SplitterMP4::Read_esds(DataReader *dr, T_esds_data *esds){ unsigned char tag; unsigned char temp2 = 0; int len; unsigned int temp; dr->GetByte(&esds->version); esds->flags = Get_24(dr); esds->decoderConfigLen = 0; /* get and verify ES_DescrTag */ dr->GetByte(&tag); if ( tag == 0x03 ) { len = Read_mp4_descr_length(dr); dr->GetShort(&esds->es_ID); dr->GetByte(&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->GetByte(&tag); len -= 1; switch ( tag ) { case 0x04: // verify DecoderConfigDescrTag { Read_mp4_descr_length(dr); dr->GetByte(&esds->objectTypeID); dr->GetByte(&esds->streamType); // 3 - video, 4 - graphic, 5 - audio esds->bufferSizeDB = Get_24(dr); dr->GetUInt(&esds->maxBitrate); dr->GetUInt(&esds->avgBitrate); len -= 17; break; } case 0x05: // verify DecSpecificInfoTag { esds->decoderConfigLen = Read_mp4_descr_length(dr); if ( esds->decoderConfigLen ) { esds->decoderConfig = (unsigned char*)(ippsMalloc_8u(esds->decoderConfigLen)); // Check memory allocation if (NULL == esds->decoderConfig) { return 0; } // Zeroed allocated table memset(esds->decoderConfig, 0, esds->decoderConfigLen); esds->start = dr->GetPosition(); temp = esds->decoderConfigLen; dr->GetData(esds->decoderConfig, (vm_var32*) &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 0; } return 0;}// DINF Box// The data information box contains objects that declare the location of the media information in a track.//int SplitterMP4::Read_dinf(DataReader *dr, T_dinf_data *dinf, T_atom_mp4 *dinf_atom){ T_atom_mp4 leaf_atom; do { Read_Atom(dr, &leaf_atom); if(Compare_Atom(&leaf_atom, "dref")) { Read_dref(dr, &(dinf->dref)); } else { Atom_Skip(dr, &leaf_atom); } } while ( (dr->GetPosition() < dinf_atom->end) && (dr->GetPosition() != 0) ); return 0;}// 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.//int SplitterMP4::Read_dref(DataReader *dr, T_dref_data *dref){ unsigned int i; dr->GetByte(&dref->version); dref->flags = Get_24(dr); dr->GetUInt(&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 0; } // Zeroed allocated table memset(dref->table, 0, sizeof(T_dref_table_data) * dref->total_entries); for ( i = 0; i < dref->total_entries; i++ ) { Read_dref_table(dr, &(dref->table[i])); } return 0;}int SplitterMP4::Read_dref_table(DataReader *dr, T_dref_table_data *table){ unsigned int len; dr->GetUInt(&table->size); len = 4; dr->GetData(table->type, (vm_var32*) &len); dr->GetByte(&table->version); table->flags = Get_24(dr); table->data_reference = (char*)ippsMalloc_8u(table->size); // Check memory allocation if (NULL == table->data_reference) { return 0; } // Zeroed allocated table memset(table->data_reference, 0, table->size); len = table->size - 12; if ( table->size > 12 ) { dr->GetData(table->data_reference, (vm_var32*) &len); } table->data_reference[table->size - 12] = 0; return 0;}} // namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -