本文整理汇总了C++中AP4_TrakAtom类的典型用法代码示例。如果您正苦于以下问题:C++ AP4_TrakAtom类的具体用法?C++ AP4_TrakAtom怎么用?C++ AP4_TrakAtom使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AP4_TrakAtom类的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: if
/*----------------------------------------------------------------------
| AP4_Track::AP4_Track
+---------------------------------------------------------------------*/
AP4_Track::AP4_Track(AP4_TrakAtom& atom,
AP4_ByteStream& sample_stream,
AP4_UI32 movie_time_scale) :
m_TrakAtom(&atom),
m_TrakAtomIsOwned(false),
m_Type(TYPE_UNKNOWN),
m_SampleTable(NULL),
m_SampleTableIsOwned(true),
m_MovieTimeScale(movie_time_scale),
m_MediaTimeScale(0)
{
// find the handler type
AP4_Atom* sub = atom.FindChild("mdia/hdlr");
if (sub) {
AP4_HdlrAtom* hdlr = dynamic_cast<AP4_HdlrAtom*>(sub);
if (hdlr) {
AP4_Atom::Type type = hdlr->GetHandlerType();
if (type == AP4_HANDLER_TYPE_SOUN) {
m_Type = TYPE_AUDIO;
} else if (type == AP4_HANDLER_TYPE_VIDE) {
m_Type = TYPE_VIDEO;
} else if (type == AP4_HANDLER_TYPE_TEXT) {
m_Type = TYPE_TEXT;
} else if (type == AP4_HANDLER_TYPE_TX3G) {
m_Type = TYPE_TEXT;
} else if (type == AP4_HANDLER_TYPE_SUBP) {
m_Type = TYPE_SUBP;
} else if (type == AP4_HANDLER_TYPE_HINT) {
m_Type = TYPE_HINT;
}
}
}
// get the media time scale
sub = atom.FindChild("mdia/mdhd");
if (sub) {
AP4_MdhdAtom* mdhd = dynamic_cast<AP4_MdhdAtom*>(sub);
if (mdhd) {
m_MediaTimeScale = mdhd->GetTimeScale();
}
}
// create a facade for the stbl atom
AP4_ContainerAtom* stbl = dynamic_cast<AP4_ContainerAtom*>(
atom.FindChild("mdia/minf/stbl"));
if (stbl) {
m_SampleTable = DNew AP4_AtomSampleTable(stbl, sample_stream);
}
}
示例2: if
/*----------------------------------------------------------------------
| AP4_Track::AP4_Track
+---------------------------------------------------------------------*/
AP4_Track::AP4_Track(AP4_TrakAtom& atom,
AP4_ByteStream& sample_stream,
AP4_UI32 movie_time_scale) :
m_TrakAtom(&atom),
m_TrakAtomIsOwned(false),
m_Type(TYPE_UNKNOWN),
m_SampleTable(NULL),
m_SampleTableIsOwned(true),
m_MovieTimeScale(movie_time_scale)
{
// find the handler type
AP4_Atom* sub = atom.FindChild("mdia/hdlr");
if (sub) {
AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, sub);
if (hdlr) {
AP4_UI32 type = hdlr->GetHandlerType();
if (type == AP4_HANDLER_TYPE_SOUN) {
m_Type = TYPE_AUDIO;
} else if (type == AP4_HANDLER_TYPE_VIDE) {
m_Type = TYPE_VIDEO;
} else if (type == AP4_HANDLER_TYPE_HINT) {
m_Type = TYPE_HINT;
} else if (type == AP4_HANDLER_TYPE_ODSM ||
type == AP4_HANDLER_TYPE_SDSM) {
m_Type = TYPE_SYSTEM;
} else if (type == AP4_HANDLER_TYPE_TEXT ||
type == AP4_HANDLER_TYPE_TX3G) {
m_Type = TYPE_TEXT;
} else if (type == AP4_HANDLER_TYPE_JPEG) {
m_Type = TYPE_JPEG;
} else if (type == AP4_HANDLER_TYPE_SUBT) {
m_Type = TYPE_SUBTITLES;
}
}
}
// create a facade for the stbl atom
AP4_ContainerAtom* stbl = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom.FindChild("mdia/minf/stbl"));
if (stbl) {
m_SampleTable = new AP4_AtomSampleTable(stbl, sample_stream);
}
}
示例3: while
/*----------------------------------------------------------------------
| AP4_Processor::Process
+---------------------------------------------------------------------*/
AP4_Result
AP4_Processor::Process(AP4_ByteStream& input,
AP4_ByteStream& output,
ProgressListener* listener,
AP4_AtomFactory& atom_factory)
{
// read all atoms
AP4_AtomParent top_level;
AP4_Atom* atom;
while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(input, atom))) {
top_level.AddChild(atom);
}
// remove the [mdat] atom, keep a ref to [moov]
AP4_MoovAtom* moov = NULL;
AP4_List<AP4_Atom>::Item* atom_item = top_level.GetChildren().FirstItem();
while (atom_item) {
atom = atom_item->GetData();
AP4_List<AP4_Atom>::Item* next = atom_item->GetNext();
if (atom->GetType() == AP4_ATOM_TYPE_MDAT) {
atom->Detach();
delete atom;
} else if (atom->GetType() == AP4_ATOM_TYPE_MOOV) {
moov = (AP4_MoovAtom*)atom;
}
atom_item = next;
}
// initialize the processor
AP4_Result result = Initialize(top_level, input);
if (AP4_FAILED(result)) return result;
// process the tracks if we have a moov atom
AP4_Array<AP4_SampleLocator> locators;
AP4_Cardinal track_count = 0;
AP4_List<AP4_TrakAtom>* trak_atoms = NULL;
AP4_LargeSize mdat_payload_size = 0;
TrackHandler** handlers = NULL;
AP4_SampleCursor* cursors = NULL;
if (moov) {
// build an array of track sample locators
trak_atoms = &moov->GetTrakAtoms();
track_count = trak_atoms->ItemCount();
cursors = new AP4_SampleCursor[track_count];
handlers = new TrackHandler*[track_count];
for (AP4_Ordinal i=0; i<track_count; i++) {
handlers[i] = NULL;
}
unsigned int index = 0;
for (AP4_List<AP4_TrakAtom>::Item* item = trak_atoms->FirstItem(); item; item=item->GetNext()) {
AP4_TrakAtom* trak = item->GetData();
// find the stsd atom
AP4_ContainerAtom* stbl = AP4_DYNAMIC_CAST(AP4_ContainerAtom, trak->FindChild("mdia/minf/stbl"));
if (stbl == NULL) continue;
// see if there's an external data source for this track
AP4_ByteStream* trak_data_stream = &input;
for (AP4_List<ExternalTrackData>::Item* ditem = m_ExternalTrackData.FirstItem(); ditem; ditem=ditem->GetNext()) {
ExternalTrackData* tdata = ditem->GetData();
if (tdata->m_TrackId == trak->GetId()) {
trak_data_stream = tdata->m_MediaData;
break;
}
}
// create the track handler
handlers[index] = CreateTrackHandler(trak);
cursors[index].m_Locator.m_TrakIndex = index;
cursors[index].m_Locator.m_SampleTable = new AP4_AtomSampleTable(stbl, *trak_data_stream);
cursors[index].m_Locator.m_SampleIndex = 0;
cursors[index].m_Locator.m_ChunkIndex = 0;
cursors[index].m_Locator.m_SampleTable->GetSample(0, cursors[index].m_Locator.m_Sample);
index++;
}
// figure out the layout of the chunks
for (;;) {
// see which is the next sample to write
AP4_UI64 min_offset = (AP4_UI64)(-1);
int cursor = -1;
for (unsigned int i=0; i<track_count; i++) {
if (!cursors[i].m_EndReached &&
cursors[i].m_Locator.m_Sample.GetOffset() <= min_offset) {
min_offset = cursors[i].m_Locator.m_Sample.GetOffset();
cursor = i;
}
}
// stop if all cursors are exhausted
if (cursor == -1) break;
// append this locator to the layout list
AP4_SampleLocator& locator = cursors[cursor].m_Locator;
locators.Append(locator);
//.........这里部分代码省略.........
示例4: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| AP4_MarlinIpmpEncryptingProcessor::Initialize
+---------------------------------------------------------------------*/
AP4_Result
AP4_MarlinIpmpEncryptingProcessor::Initialize(
AP4_AtomParent& top_level,
AP4_ByteStream& /*stream*/,
AP4_Processor::ProgressListener* /*listener = NULL*/)
{
// get the moov atom
AP4_MoovAtom* moov = AP4_DYNAMIC_CAST(AP4_MoovAtom, top_level.GetChild(AP4_ATOM_TYPE_MOOV));
if (moov == NULL) return AP4_ERROR_INVALID_FORMAT;
// deal with the file type
AP4_FtypAtom* ftyp = AP4_DYNAMIC_CAST(AP4_FtypAtom, top_level.GetChild(AP4_ATOM_TYPE_FTYP));
if (ftyp) {
// remove the atom, it will be replaced with a new one
top_level.RemoveChild(ftyp);
// keep the existing brand and compatible brands
AP4_Array<AP4_UI32> compatible_brands;
compatible_brands.EnsureCapacity(ftyp->GetCompatibleBrands().ItemCount()+1);
for (unsigned int i=0; i<ftyp->GetCompatibleBrands().ItemCount(); i++) {
compatible_brands.Append(ftyp->GetCompatibleBrands()[i]);
}
// add the MGSV compatible brand if it is not already there
if (!ftyp->HasCompatibleBrand(AP4_MARLIN_BRAND_MGSV)) {
compatible_brands.Append(AP4_MARLIN_BRAND_MGSV);
}
// create a replacement for the major brand
AP4_FtypAtom* new_ftyp = new AP4_FtypAtom(AP4_MARLIN_BRAND_MGSV,
0x13c078c, //AP4_MARLIN_BRAND_MGSV_MAJOR_VERSION,
&compatible_brands[0],
compatible_brands.ItemCount());
delete ftyp;
ftyp = new_ftyp;
} else {
AP4_UI32 isom = AP4_FTYP_BRAND_ISOM;
ftyp = new AP4_FtypAtom(AP4_MARLIN_BRAND_MGSV, 0, &isom, 1);
}
// insert the ftyp atom as the first child
top_level.AddChild(ftyp, 0);
// create and 'mpod' track reference atom
AP4_TrefTypeAtom* mpod = new AP4_TrefTypeAtom(AP4_ATOM_TYPE_MPOD);
// look for an available track ID, starting at 1
unsigned int od_track_id = 0;
unsigned int od_track_position = 0;
AP4_List<AP4_TrakAtom>::Item* trak_item = moov->GetTrakAtoms().FirstItem();
while (trak_item) {
AP4_TrakAtom* trak = trak_item->GetData();
if (trak) {
od_track_position++;
if (trak->GetId() >= od_track_id) {
od_track_id = trak->GetId()+1;
}
// if the track is encrypted, reference it in the mpod
if (m_KeyMap.GetKey(trak->GetId())) {
mpod->AddTrackId(trak->GetId());
}
//m_SinfEntries.Add(new SinfEntry(trak->GetId(), NULL));
}
trak_item = trak_item->GetNext();
}
// check that there was at least one track in the file
if (od_track_id == 0) return AP4_ERROR_INVALID_FORMAT;
// create an initial object descriptor
AP4_InitialObjectDescriptor* iod =
// FIXME: get real values from the property map
new AP4_InitialObjectDescriptor(AP4_DESCRIPTOR_TAG_MP4_IOD,
1022, // object descriptor id
false,
0xFE, // OD profile level (0xFE = No OD profile specified)
0xFF, // scene profile level
0xFE, // audio profile level
0xFE, // visual profile level
0xFF); // graphics profile
// create an ES_ID_Inc subdescriptor and add it to the initial object descriptor
AP4_EsIdIncDescriptor* es_id_inc = new AP4_EsIdIncDescriptor(od_track_id);
iod->AddSubDescriptor(es_id_inc);
// create an iods atom to hold the initial object descriptor
AP4_IodsAtom* iods = new AP4_IodsAtom(iod);
// add the iods atom to the moov atom (try to put it just after mvhd)
int iods_position = 0;
int item_position = 0;
for (AP4_List<AP4_Atom>::Item* item = moov->GetChildren().FirstItem();
item;
++item) {
++item_position;
//.........这里部分代码省略.........
示例5: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| AP4_MarlinIpmpEncryptingProcessor::Initialize
+---------------------------------------------------------------------*/
AP4_Result
AP4_MarlinIpmpEncryptingProcessor::Initialize(
AP4_AtomParent& top_level,
AP4_ByteStream& /*stream*/,
AP4_Processor::ProgressListener* /*listener = NULL*/)
{
// get the moov atom
AP4_MoovAtom* moov = AP4_DYNAMIC_CAST(AP4_MoovAtom, top_level.GetChild(AP4_ATOM_TYPE_MOOV));
if (moov == NULL) return AP4_ERROR_INVALID_FORMAT;
// deal with the file type
AP4_FtypAtom* ftyp = AP4_DYNAMIC_CAST(AP4_FtypAtom, top_level.GetChild(AP4_ATOM_TYPE_FTYP));
if (ftyp) {
// remove the atom, it will be replaced with a new one
top_level.RemoveChild(ftyp);
// keep the existing brand and compatible brands
AP4_Array<AP4_UI32> compatible_brands;
compatible_brands.EnsureCapacity(ftyp->GetCompatibleBrands().ItemCount()+1);
for (unsigned int i=0; i<ftyp->GetCompatibleBrands().ItemCount(); i++) {
compatible_brands.Append(ftyp->GetCompatibleBrands()[i]);
}
// add the MGSV compatible brand if it is not already there
if (!ftyp->HasCompatibleBrand(AP4_MARLIN_BRAND_MGSV)) {
compatible_brands.Append(AP4_MARLIN_BRAND_MGSV);
}
// create a replacement for the major brand
AP4_FtypAtom* new_ftyp = new AP4_FtypAtom(AP4_MARLIN_BRAND_MGSV,
0x13c078c, //AP4_MARLIN_BRAND_MGSV_MAJOR_VERSION,
&compatible_brands[0],
compatible_brands.ItemCount());
delete ftyp;
ftyp = new_ftyp;
} else {
AP4_UI32 isom = AP4_FTYP_BRAND_ISOM;
ftyp = new AP4_FtypAtom(AP4_MARLIN_BRAND_MGSV, 0, &isom, 1);
}
// insert the ftyp atom as the first child
top_level.AddChild(ftyp, 0);
// create and 'mpod' track reference atom
AP4_TrefTypeAtom* mpod = new AP4_TrefTypeAtom(AP4_ATOM_TYPE_MPOD);
// look for an available track ID, starting at 1
unsigned int od_track_id = 0;
unsigned int od_track_position = 0;
for (AP4_List<AP4_TrakAtom>::Item* trak_item = moov->GetTrakAtoms().FirstItem();
trak_item;
trak_item = trak_item->GetNext()) {
AP4_TrakAtom* trak = trak_item->GetData();
if (trak) {
od_track_position++;
if (trak->GetId() >= od_track_id) {
od_track_id = trak->GetId()+1;
}
// if the track is encrypted, reference it in the mpod
if (m_KeyMap.GetKey(trak->GetId())) {
mpod->AddTrackId(trak->GetId());
}
//m_SinfEntries.Add(new SinfEntry(trak->GetId(), NULL));
}
}
// check that there was at least one track in the file
if (od_track_id == 0) return AP4_ERROR_INVALID_FORMAT;
// create an initial object descriptor
AP4_InitialObjectDescriptor* iod =
// FIXME: get real values from the property map
new AP4_InitialObjectDescriptor(AP4_DESCRIPTOR_TAG_MP4_IOD,
1022, // object descriptor id
false,
0xFE, // OD profile level (0xFE = No OD profile specified)
0xFF, // scene profile level
0xFE, // audio profile level
0xFE, // visual profile level
0xFF); // graphics profile
// create an ES_ID_Inc subdescriptor and add it to the initial object descriptor
AP4_EsIdIncDescriptor* es_id_inc = new AP4_EsIdIncDescriptor(od_track_id);
iod->AddSubDescriptor(es_id_inc);
// create an iods atom to hold the initial object descriptor
AP4_IodsAtom* iods = new AP4_IodsAtom(iod);
// add the iods atom to the moov atom (try to put it just after mvhd)
int iods_position = 0;
int item_position = 0;
for (AP4_List<AP4_Atom>::Item* moov_item = moov->GetChildren().FirstItem();
moov_item;
moov_item = moov_item->GetNext()) {
++item_position;
//.........这里部分代码省略.........
示例6: AP4_SUCCEEDED
/*----------------------------------------------------------------------
| AP4_Processor::Process
+---------------------------------------------------------------------*/
AP4_Result
AP4_Processor::Process(AP4_ByteStream& input,
AP4_ByteStream& output,
AP4_ByteStream* fragments,
ProgressListener* listener,
AP4_AtomFactory& atom_factory)
{
// read all atoms.
// keep all atoms except [mdat]
// keep a ref to [moov]
// put [moof] atoms in a separate list
AP4_AtomParent top_level;
AP4_MoovAtom* moov = NULL;
AP4_ContainerAtom* mfra = NULL;
AP4_SidxAtom* sidx = NULL;
AP4_List<AP4_AtomLocator> frags;
AP4_UI64 stream_offset = 0;
bool in_fragments = false;
unsigned int sidx_count = 0;
for (AP4_Atom* atom = NULL;
AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(input, atom));
input.Tell(stream_offset)) {
if (atom->GetType() == AP4_ATOM_TYPE_MDAT) {
delete atom;
continue;
} else if (atom->GetType() == AP4_ATOM_TYPE_MOOV) {
moov = AP4_DYNAMIC_CAST(AP4_MoovAtom, atom);
if (fragments) break;
} else if (atom->GetType() == AP4_ATOM_TYPE_MFRA) {
mfra = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
continue;
} else if (atom->GetType() == AP4_ATOM_TYPE_SIDX) {
// don't keep the index, it is likely to be invalidated, we will recompute it later
++sidx_count;
if (sidx == NULL) {
sidx = AP4_DYNAMIC_CAST(AP4_SidxAtom, atom);
} else {
delete atom;
continue;
}
} else if (atom->GetType() == AP4_ATOM_TYPE_SSIX) {
// don't keep the index, it is likely to be invalidated
delete atom;
continue;
} else if (!fragments && (in_fragments || atom->GetType() == AP4_ATOM_TYPE_MOOF)) {
in_fragments = true;
frags.Add(new AP4_AtomLocator(atom, stream_offset));
break;
}
top_level.AddChild(atom);
}
// check that we have at most one sidx (we can't deal with multi-sidx streams here
if (sidx_count > 1) {
top_level.RemoveChild(sidx);
delete sidx;
sidx = NULL;
}
// if we have a fragments stream, get the fragment locators from there
if (fragments) {
stream_offset = 0;
for (AP4_Atom* atom = NULL;
AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*fragments, atom));
fragments->Tell(stream_offset)) {
if (atom->GetType() == AP4_ATOM_TYPE_MDAT) {
delete atom;
continue;
}
frags.Add(new AP4_AtomLocator(atom, stream_offset));
}
}
// initialize the processor
AP4_Result result = Initialize(top_level, input);
if (AP4_FAILED(result)) return result;
// process the tracks if we have a moov atom
AP4_Array<AP4_SampleLocator> locators;
AP4_Cardinal track_count = 0;
AP4_List<AP4_TrakAtom>* trak_atoms = NULL;
AP4_LargeSize mdat_payload_size = 0;
AP4_SampleCursor* cursors = NULL;
if (moov) {
// build an array of track sample locators
trak_atoms = &moov->GetTrakAtoms();
track_count = trak_atoms->ItemCount();
cursors = new AP4_SampleCursor[track_count];
m_TrackData.SetItemCount(track_count);
m_StreamData.SetItemCount(1);
m_StreamData[0].stream = &input;
unsigned int index = 0;
for (AP4_List<AP4_TrakAtom>::Item* item = trak_atoms->FirstItem(); item; item=item->GetNext()) {
AP4_TrakAtom* trak = item->GetData();
// find the stsd atom
//.........这里部分代码省略.........
示例7: main
//.........这里部分代码省略.........
} else if (Options.track_id) {
AP4_Track* track = movie->GetTrack(Options.track_id);
if (track == NULL) {
fprintf(stderr, "--track-id option specified, but no such track found\n");
return 1;
}
Options.track_filter = track->GetId();
}
// save the init segment
AP4_ByteStream* output = NULL;
result = AP4_FileByteStream::Create(Options.init_segment_name, AP4_FileByteStream::STREAM_MODE_WRITE, output);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot open output file (%d)\n", result);
return 1;
}
AP4_FtypAtom* ftyp = file->GetFileType();
if (ftyp) {
result = ftyp->Write(*output);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot write ftyp segment (%d)\n", result);
return 1;
}
}
if (Options.track_filter) {
AP4_MoovAtom* moov = movie->GetMoovAtom();
// only keep the 'trak' atom that we need
AP4_List<AP4_Atom>::Item* child = moov->GetChildren().FirstItem();
while (child) {
AP4_Atom* atom = child->GetData();
child = child->GetNext();
if (atom->GetType() == AP4_ATOM_TYPE_TRAK) {
AP4_TrakAtom* trak = (AP4_TrakAtom*)atom;
AP4_TkhdAtom* tkhd = (AP4_TkhdAtom*)trak->GetChild(AP4_ATOM_TYPE_TKHD);
if (tkhd && tkhd->GetTrackId() != Options.track_filter) {
atom->Detach();
delete atom;
}
}
}
// only keep the 'trex' atom that we need
AP4_ContainerAtom* mvex = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov->GetChild(AP4_ATOM_TYPE_MVEX));
if (mvex) {
child = mvex->GetChildren().FirstItem();
while (child) {
AP4_Atom* atom = child->GetData();
child = child->GetNext();
if (atom->GetType() == AP4_ATOM_TYPE_TREX) {
AP4_TrexAtom* trex = AP4_DYNAMIC_CAST(AP4_TrexAtom, atom);
if (trex && trex->GetTrackId() != Options.track_filter) {
atom->Detach();
delete atom;
}
}
}
}
}
result = movie->GetMoovAtom()->Write(*output);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot write init segment (%d)\n", result);
return 1;
}
AP4_Atom* atom = NULL;
示例8: while
/*----------------------------------------------------------------------
| AP4_Processor::Process
+---------------------------------------------------------------------*/
AP4_Result
AP4_Processor::Process(AP4_ByteStream& input,
AP4_ByteStream& output,
AP4_AtomFactory& atom_factory)
{
// read all atoms
AP4_AtomParent top_level;
AP4_Atom* atom;
while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(input, atom))) {
top_level.AddChild(atom);
}
// remove the [mdat] and [free] atoms, keep a ref to [moov]
AP4_MoovAtom* moov = NULL;
AP4_List<AP4_Atom>::Item* atom_item = top_level.GetChildren().FirstItem();
while (atom_item) {
atom = atom_item->GetData();
AP4_List<AP4_Atom>::Item* next = atom_item->GetNext();
if (//atom->GetType() == AP4_ATOM_TYPE_FREE ||
atom->GetType() == AP4_ATOM_TYPE_MDAT) {
atom->Detach();
delete atom;
} else if (atom->GetType() == AP4_ATOM_TYPE_MOOV) {
moov = (AP4_MoovAtom*)atom;
}
atom_item = next;
}
// check that we have a moov atom
if (moov == NULL) return AP4_FAILURE;
// initialize the processor
AP4_Result result = Initialize(top_level);
if (AP4_FAILED(result)) return result;
// build an array of track sample cursors
AP4_List<AP4_TrakAtom>& trak_atoms = moov->GetTrakAtoms();
AP4_Cardinal track_count = trak_atoms.ItemCount();
AP4_SampleCursor* cursors = new AP4_SampleCursor[track_count];
TrackHandler** handlers = new TrackHandler*[track_count];
AP4_List<AP4_TrakAtom>::Item* item = trak_atoms.FirstItem();
unsigned int index = 0;
while (item) {
// create the track handler // find the stsd atom
AP4_ContainerAtom* stbl = dynamic_cast<AP4_ContainerAtom*>(
item->GetData()->FindChild("mdia/minf/stbl"));
if (stbl == NULL) continue;
handlers[index] = CreateTrackHandler(item->GetData());
cursors[index].m_Locator.m_TrakIndex = index;
cursors[index].m_Locator.m_SampleTable = new AP4_AtomSampleTable(stbl, input);
cursors[index].m_Locator.m_SampleIndex = 0;
cursors[index].m_Locator.m_SampleTable->GetSample(0, cursors[index].m_Locator.m_Sample);
cursors[index].m_Locator.m_Chunk = 1;
index++;
item = item->GetNext();
}
// figure out the layout of the chunks
AP4_Array<AP4_SampleLocator> locators;
for (;;) {
// see which is the next sample to write
unsigned int min_offset = 0xFFFFFFFF;
int cursor = -1;
for (unsigned int i=0; i<track_count; i++) {
if (cursors[i].m_Locator.m_SampleTable &&
cursors[i].m_Locator.m_Sample.GetOffset() <= min_offset) {
min_offset = cursors[i].m_Locator.m_Sample.GetOffset();
cursor = i;
}
}
// stop if all cursors are exhausted
if (cursor == -1) break;
// append this locator to the layout list
AP4_SampleLocator& locator = cursors[cursor].m_Locator;
locators.Append(locator);
//AP4_Debug("NEXT: track %d, sample %d:%d: offset=%d, size=%d\n",
// locator.m_TrakIndex,
// locator.m_Chunk,
// locator.m_SampleIndex,
// locator.m_Sample.GetOffset(),
// locator.m_Sample.GetSize());
// move the cursor to the next sample
locator.m_SampleIndex++;
if (locator.m_SampleIndex == locator.m_SampleTable->GetSampleCount()) {
// mark this track as completed
locator.m_SampleTable = NULL;
} else {
// get the next sample info
locator.m_SampleTable->GetSample(locator.m_SampleIndex,
locator.m_Sample);
AP4_Ordinal skip, sdesc;
locator.m_SampleTable->GetChunkForSample(locator.m_SampleIndex+1, // the internal API is 1-based
locator.m_Chunk,
skip, sdesc);
//.........这里部分代码省略.........