本文整理汇总了C++中AP4_Array类的典型用法代码示例。如果您正苦于以下问题:C++ AP4_Array类的具体用法?C++ AP4_Array怎么用?C++ AP4_Array使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AP4_Array类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: if
/*----------------------------------------------------------------------
| AP4_TrakAtom::GetChunkOffsets
+---------------------------------------------------------------------*/
AP4_Result
AP4_TrakAtom::GetChunkOffsets(AP4_Array<AP4_UI64>& chunk_offsets)
{
AP4_Atom* atom;
if ((atom = FindChild("mdia/minf/stbl/stco"))) {
AP4_StcoAtom* stco = AP4_DYNAMIC_CAST(AP4_StcoAtom, atom);
if (stco == NULL) return AP4_ERROR_INTERNAL;
AP4_Cardinal stco_chunk_count = stco->GetChunkCount();
const AP4_UI32* stco_chunk_offsets = stco->GetChunkOffsets();
chunk_offsets.SetItemCount(stco_chunk_count);
for (unsigned int i=0; i<stco_chunk_count; i++) {
chunk_offsets[i] = stco_chunk_offsets[i];
}
return AP4_SUCCESS;
} else if ((atom = FindChild("mdia/minf/stbl/co64"))) {
AP4_Co64Atom* co64 = AP4_DYNAMIC_CAST(AP4_Co64Atom, atom);
if (co64 == NULL) return AP4_ERROR_INTERNAL;
AP4_Cardinal co64_chunk_count = co64->GetChunkCount();
const AP4_UI64* co64_chunk_offsets = co64->GetChunkOffsets();
chunk_offsets.SetItemCount(co64_chunk_count);
for (unsigned int i=0; i<co64_chunk_count; i++) {
chunk_offsets[i] = co64_chunk_offsets[i];
}
return AP4_SUCCESS;
} else {
return AP4_ERROR_INVALID_STATE;
}
}
示例2:
/*----------------------------------------------------------------------
| AP4_AvccAtom::AP4_AvccAtom
+---------------------------------------------------------------------*/
AP4_AvccAtom::AP4_AvccAtom(AP4_UI08 config_version,
AP4_UI08 profile,
AP4_UI08 level,
AP4_UI08 profile_compatibility,
AP4_UI08 length_size,
const AP4_Array<AP4_DataBuffer>& sequence_parameters,
const AP4_Array<AP4_DataBuffer>& picture_parameters) :
AP4_Atom(AP4_ATOM_TYPE_AVCC, AP4_ATOM_HEADER_SIZE+7),
m_ConfigurationVersion(config_version),
m_Profile(profile),
m_Level(level),
m_ProfileCompatibility(profile_compatibility),
m_NaluLengthSize(length_size)
{
// deep copy of the parameters
unsigned int i = 0;
for (i=0; i<sequence_parameters.ItemCount(); i++) {
m_SequenceParameters.Append(sequence_parameters[i]);
m_Size32 += 2+sequence_parameters[i].GetDataSize();
}
for (i=0; i<picture_parameters.ItemCount(); i++) {
m_PictureParameters.Append(picture_parameters[i]);
m_Size32 += 2+picture_parameters[i].GetDataSize();
}
}
示例3: UpdateRawBytes
/*----------------------------------------------------------------------
| AP4_AvccAtom::AP4_AvccAtom
+---------------------------------------------------------------------*/
AP4_AvccAtom::AP4_AvccAtom(AP4_UI08 profile,
AP4_UI08 level,
AP4_UI08 profile_compatibility,
AP4_UI08 length_size,
const AP4_Array<AP4_DataBuffer>& sequence_parameters,
const AP4_Array<AP4_DataBuffer>& picture_parameters) :
AP4_Atom(AP4_ATOM_TYPE_AVCC, AP4_ATOM_HEADER_SIZE),
m_ConfigurationVersion(1),
m_Profile(profile),
m_Level(level),
m_ProfileCompatibility(profile_compatibility),
m_NaluLengthSize(length_size)
{
// deep copy of the parameters
unsigned int i = 0;
for (i=0; i<sequence_parameters.ItemCount(); i++) {
m_SequenceParameters.Append(sequence_parameters[i]);
}
for (i=0; i<picture_parameters.ItemCount(); i++) {
m_PictureParameters.Append(picture_parameters[i]);
}
// compute the raw bytes
UpdateRawBytes();
// update the size
m_Size32 += m_RawBytes.GetDataSize();
}
示例4: ProcessMoof
/*----------------------------------------------------------------------
| ProcessMoof
+---------------------------------------------------------------------*/
static int
ProcessMoof(AP4_Movie* movie,
AP4_ContainerAtom* moof,
AP4_ByteStream* sample_stream,
AP4_Position moof_offset,
AP4_Position mdat_payload_offset)
{
AP4_Result result;
AP4_MovieFragment* fragment = new AP4_MovieFragment(moof);
printf("fragment sequence number=%d\n", fragment->GetSequenceNumber());
AP4_FragmentSampleTable* sample_table = NULL;
// get all track IDs in this fragment
AP4_Array<AP4_UI32> ids;
fragment->GetTrackIds(ids);
printf("Found %d tracks in fragment: ", ids.ItemCount());
for (unsigned int i=0; i<ids.ItemCount(); i++) {
printf("%d ", ids[i]);
}
printf("\n");
for (unsigned int i=0; i<ids.ItemCount(); i++) {
AP4_Track* track = NULL;
if (movie) {
track = movie->GetTrack(ids[i]);
}
AP4_ContainerAtom* traf = NULL;
fragment->GetTrafAtom(ids[i], traf);
printf("processing moof for track id %d\n", ids[i]);
result = fragment->CreateSampleTable(movie, ids[i], sample_stream, moof_offset, mdat_payload_offset, sample_table);
CHECK(result == AP4_SUCCESS || result == AP4_ERROR_NO_SUCH_ITEM);
if (AP4_SUCCEEDED(result) ) {
ProcessSamples(track, traf, sample_table);
delete sample_table;
} else {
printf("no sample table for this track\n");
}
}
delete fragment;
return 0;
}
示例5: AP4_MovieFragment
/*----------------------------------------------------------------------
| AP4_LinearReader::ProcessMoof
+---------------------------------------------------------------------*/
AP4_Result
AP4_LinearReader::ProcessMoof(AP4_ContainerAtom* moof,
AP4_Position moof_offset,
AP4_Position mdat_payload_offset)
{
AP4_Result result;
// create a new fragment
delete m_Fragment;
m_Fragment = new AP4_MovieFragment(moof);
// update the trackers
AP4_Array<AP4_UI32> ids;
m_Fragment->GetTrackIds(ids);
for (unsigned int i=0; i<m_Trackers.ItemCount(); i++) {
Tracker* tracker = m_Trackers[i];
if (tracker->m_SampleTableIsOwned) {
delete tracker->m_SampleTable;
}
tracker->m_SampleTable = NULL;
tracker->m_NextSampleIndex = 0;
for (unsigned int j=0; j<ids.ItemCount(); j++) {
if (ids[j] == tracker->m_Track->GetId()) {
AP4_FragmentSampleTable* sample_table = NULL;
result = m_Fragment->CreateSampleTable(&m_Movie,
ids[j],
m_FragmentStream,
moof_offset,
mdat_payload_offset,
tracker->m_NextDts,
sample_table);
if (AP4_FAILED(result)) return result;
tracker->m_SampleTable = sample_table;
tracker->m_SampleTableIsOwned = true;
tracker->m_Eos = false;
break;
}
}
}
return AP4_SUCCESS;
}
示例6: DumpTrackData
/*----------------------------------------------------------------------
| DumpTrackData
+---------------------------------------------------------------------*/
void
DumpTrackData(const char* mp4_filename,
AP4_File& mp4_file,
const AP4_Array<AP4_Ordinal>& tracks_to_dump,
const AP4_ProtectionKeyMap& key_map)
{
// dump all the tracks that need to be dumped
AP4_Cardinal tracks_to_dump_count = tracks_to_dump.ItemCount();
for (AP4_Ordinal i=0; i<tracks_to_dump_count; i++) {
// get the track
AP4_Ordinal track_id = tracks_to_dump[i];
AP4_Track* track = mp4_file.GetMovie()->GetTrack(track_id);
if (track == NULL) {
fprintf(stderr, "track not found (id = %d)", track_id);
return;
}
// get the sample description
AP4_SampleDescription* sample_description = track->GetSampleDescription(0);
if (sample_description == NULL) {
fprintf(stderr, "WARNING: unable to parse sample description\n");
}
// get the dump data byte stream
AP4_ByteStream* dump = CreateTrackDumpByteStream(mp4_filename, track_id);
if (dump == NULL) return;
printf("\nDumping data for track %d:\n", track_id);
switch(sample_description ?
sample_description->GetType() :
AP4_SampleDescription::TYPE_UNKNOWN) {
case AP4_SampleDescription::TYPE_PROTECTED:
{
const AP4_DataBuffer* key = key_map.GetKey(track_id);
if (key == NULL) {
fprintf(stderr,
"WARNING: No key found for encrypted track %d... "
"dumping encrypted samples\n",
track_id);
DumpSamples(track, dump);
} else {
DecryptAndDumpSamples(track, sample_description, key->GetData(), key->GetDataSize(), dump);
}
}
break;
default:
DumpSamples(track, dump);
}
dump->Release();
}
}
示例7: main
//.........这里部分代码省略.........
result = AP4_FileByteStream::Create(input_filename,
AP4_FileByteStream::STREAM_MODE_READ,
input_stream);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot open input (%d)\n", result);
return 1;
}
if (output_filename == NULL) {
fprintf(stderr, "ERROR: no output specified\n");
return 1;
}
AP4_ByteStream* output_stream = NULL;
result = AP4_FileByteStream::Create(output_filename,
AP4_FileByteStream::STREAM_MODE_WRITE,
output_stream);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot create/open output (%d)\n", result);
return 1;
}
// parse the input MP4 file (moov only)
AP4_File input_file(*input_stream, AP4_DefaultAtomFactory::Instance, true);
// check the file for basic properties
if (input_file.GetMovie() == NULL) {
fprintf(stderr, "ERROR: no movie found in the file\n");
return 1;
}
if (!quiet && input_file.GetMovie()->HasFragments()) {
fprintf(stderr, "NOTICE: file is already fragmented, it will be re-fragmented\n");
}
// create a cusor list to keep track of the tracks we will read from
AP4_Array<TrackCursor*> cursors;
// iterate over all tracks
TrackCursor* video_track = NULL;
TrackCursor* audio_track = NULL;
TrackCursor* subtitles_track = NULL;
unsigned int video_track_count = 0;
unsigned int audio_track_count = 0;
unsigned int subtitles_track_count = 0;
for (AP4_List<AP4_Track>::Item* track_item = input_file.GetMovie()->GetTracks().FirstItem();
track_item;
track_item = track_item->GetNext()) {
AP4_Track* track = track_item->GetData();
// sanity check
if (track->GetSampleCount() == 0 && !input_file.GetMovie()->HasFragments()) {
fprintf(stderr, "WARNING: track %d has no samples, it will be skipped\n", track->GetId());
continue;
}
// create a sample array for this track
SampleArray* sample_array;
if (input_file.GetMovie()->HasFragments()) {
sample_array = new CachedSampleArray(track);
} else {
sample_array = new SampleArray(track);
}
// create a cursor for the track
TrackCursor* cursor = new TrackCursor(track, sample_array);
cursor->m_Tfra->SetTrackId(track->GetId());
cursors.Append(cursor);
示例8: Fragment
/*----------------------------------------------------------------------
| Fragment
+---------------------------------------------------------------------*/
static void
Fragment(AP4_File& input_file,
AP4_ByteStream& output_stream,
AP4_Array<TrackCursor*>& cursors,
unsigned int fragment_duration,
AP4_UI32 timescale,
AP4_UI32 track_id,
bool create_segment_index)
{
AP4_List<FragmentInfo> fragments;
TrackCursor* index_cursor = NULL;
AP4_Result result;
AP4_Movie* input_movie = input_file.GetMovie();
if (input_movie == NULL) {
fprintf(stderr, "ERROR: no moov found in the input file\n");
return;
}
// create the output file object
AP4_Movie* output_movie = new AP4_Movie(1000);
// create an mvex container
AP4_ContainerAtom* mvex = new AP4_ContainerAtom(AP4_ATOM_TYPE_MVEX);
AP4_MehdAtom* mehd = new AP4_MehdAtom(0);
mvex->AddChild(mehd);
// add an output track for each track in the input file
for (unsigned int i=0; i<cursors.ItemCount(); i++) {
AP4_Track* track = cursors[i]->m_Track;
// skip non matching tracks if we have a selector
if (track_id && track->GetId() != track_id) {
continue;
}
result = cursors[i]->Init();
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: failed to init sample cursor (%d), skipping track %d\n", result, track->GetId());
return;
}
// create a sample table (with no samples) to hold the sample description
AP4_SyntheticSampleTable* sample_table = new AP4_SyntheticSampleTable();
for (unsigned int j=0; j<track->GetSampleDescriptionCount(); j++) {
AP4_SampleDescription* sample_description = track->GetSampleDescription(j);
sample_table->AddSampleDescription(sample_description, false);
}
// create the track
AP4_Track* output_track = new AP4_Track(sample_table,
track->GetId(),
timescale?timescale:1000,
AP4_ConvertTime(track->GetDuration(),
input_movie->GetTimeScale(),
timescale?timescale:1000),
timescale?timescale:track->GetMediaTimeScale(),
0,//track->GetMediaDuration(),
track);
output_movie->AddTrack(output_track);
// add a trex entry to the mvex container
AP4_TrexAtom* trex = new AP4_TrexAtom(track->GetId(),
1,
0,
0,
0);
mvex->AddChild(trex);
}
// select the anchor cursor
TrackCursor* anchor_cursor = NULL;
for (unsigned int i=0; i<cursors.ItemCount(); i++) {
if (cursors[i]->m_Track->GetId() == track_id) {
anchor_cursor = cursors[i];
}
}
if (anchor_cursor == NULL) {
for (unsigned int i=0; i<cursors.ItemCount(); i++) {
// use this as the anchor track if it is the first video track
if (cursors[i]->m_Track->GetType() == AP4_Track::TYPE_VIDEO) {
anchor_cursor = cursors[i];
break;
}
}
}
if (anchor_cursor == NULL) {
// no video track to anchor with, pick the first audio track
for (unsigned int i=0; i<cursors.ItemCount(); i++) {
if (cursors[i]->m_Track->GetType() == AP4_Track::TYPE_AUDIO) {
anchor_cursor = cursors[i];
break;
}
}
// no audio track to anchor with, pick the first subtitles track
for (unsigned int i=0; i<cursors.ItemCount(); i++) {
if (cursors[i]->m_Track->GetType() == AP4_Track::TYPE_SUBTITLES) {
//.........这里部分代码省略.........
示例9: track_count
/*----------------------------------------------------------------------
| AP4_Processor::MuxStream
+---------------------------------------------------------------------*/
AP4_Result
AP4_Processor::MuxStream(
AP4_Array<AP4_ByteStream *> &input,
AP4_ByteStream& output,
AP4_UI08 partitions,
AP4_AtomFactory& atom_factory)
{
AP4_Result result;
AP4_UI64 stream_offset = 0;
if (partitions & 1)
{
// 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_Array<AP4_MoovAtom*> moov;
AP4_Size track_count(0);
for(AP4_Size streamid(0); streamid < input.ItemCount(); ++streamid)
{
for (AP4_Atom* atom = NULL; AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*input[streamid], atom)); input[streamid]->Tell(stream_offset))
{
if (atom->GetType() == AP4_ATOM_TYPE_MFRA) {
delete atom;
continue;
}
else if (atom->GetType() == AP4_ATOM_TYPE_SIDX) {
delete atom;
continue;
}
else if (atom->GetType() == AP4_ATOM_TYPE_SSIX) {
delete atom;
continue;
}
if (streamid == 0)
top_level.AddChild(atom);
else if (atom->GetType() != AP4_ATOM_TYPE_MOOV)
delete atom;
if (atom->GetType() == AP4_ATOM_TYPE_MOOV)
{
moov.Append(AP4_DYNAMIC_CAST(AP4_MoovAtom,atom));
break;
}
}
if (moov.ItemCount() == streamid)
return AP4_ERROR_INVALID_FORMAT;
while (AP4_SUCCEEDED(moov[streamid]->DeleteChild(AP4_ATOM_TYPE_PSSH, 0)));
// Remove tracks we cannot handle
for (AP4_List<AP4_TrakAtom>::Item *item(moov[streamid]->GetTrakAtoms().FirstItem()); item;)
if (!item->GetData()->FindChild("mdia/minf/stbl"))
moov[streamid]->GetTrakAtoms().Remove(item);
else
item = item->GetNext();
track_count += moov[streamid]->GetTrakAtoms().ItemCount();
}
// initialize the processor
if (AP4_FAILED(result = Initialize(top_level, *input[0])))
return result;
// process the tracks if we have a moov atom
m_TrackData.SetItemCount(track_count);
m_StreamData.SetItemCount(input.ItemCount());
//NormalizeTREX(mvex, 0, m_TrackCounts[0], m_TrackCounts[1]);
AP4_Cardinal internal_index(0);
AP4_ContainerAtom *mvex_base(0);
AP4_List<AP4_TrakAtom>::Item *item = NULL;
for (AP4_Size streamid(0); streamid < input.ItemCount(); ++streamid)
{
m_StreamData[streamid].trackStart = internal_index;
m_StreamData[streamid].stream = input[streamid];
if (streamid)
moov[0]->AddTrakAtoms(moov[streamid]->GetTrakAtoms(), item);
else
item = moov[streamid]->GetTrakAtoms().FirstItem();
for (; item; item = item->GetNext())
{
PERTRACK &track_data(m_TrackData[internal_index]);
track_data.original_id = item->GetData()->GetId();
item->GetData()->SetId(track_data.new_id = internal_index + 1);
if (AP4_MdhdAtom* mdhd = AP4_DYNAMIC_CAST(AP4_MdhdAtom, item->GetData()->FindChild("mdia/mdhd")))
track_data.timescale = mdhd->GetTimeScale();
else
track_data.timescale = 1;
AP4_ContainerAtom *mvex = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov[streamid]->GetChild(AP4_ATOM_TYPE_MVEX, 0));
if (!mvex)
return AP4_ERROR_INVALID_FORMAT;
//.........这里部分代码省略.........
示例10: 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
//.........这里部分代码省略.........
示例11: AP4_MovieFragment
/*----------------------------------------------------------------------
| AP4_Processor::ProcessFragments
+---------------------------------------------------------------------*/
AP4_Result
AP4_Processor::ProcessFragments(AP4_MoovAtom* moov,
AP4_List<AP4_MoofLocator>& moofs,
AP4_ContainerAtom* mfra,
AP4_ByteStream& input,
AP4_ByteStream& output)
{
// FIXME: this only works for non-changing moofs
for (AP4_List<AP4_MoofLocator>::Item* item = moofs.FirstItem();
item;
item = item->GetNext()) {
AP4_MoofLocator* locator = item->GetData();
AP4_ContainerAtom* moof = locator->m_Moof;
AP4_UI64 moof_offset = locator->m_Offset;
AP4_UI64 mdat_payload_offset = moof_offset+moof->GetSize()+8;
AP4_MovieFragment* fragment = new AP4_MovieFragment(moof);
AP4_Sample sample;
AP4_DataBuffer sample_data_in;
AP4_DataBuffer sample_data_out;
AP4_Result result;
// process all the traf atoms
AP4_Array<AP4_Processor::FragmentHandler*> handlers;
for (;AP4_Atom* atom = moof->GetChild(AP4_ATOM_TYPE_TRAF, handlers.ItemCount());) {
AP4_ContainerAtom* traf = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
AP4_Processor::FragmentHandler* handler = CreateFragmentHandler(traf);
if (handler) result = handler->ProcessFragment();
handlers.Append(handler);
}
// write the moof
AP4_UI64 moof_out_start = 0;
output.Tell(moof_out_start);
bool moof_has_changed = false;
moof->Write(output);
// process all track runs
for (unsigned int i=0; i<handlers.ItemCount(); i++) {
AP4_FragmentSampleTable* sample_table = NULL;
AP4_Processor::FragmentHandler* handler = handlers[i];
// get the track ID
AP4_ContainerAtom* traf = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moof->GetChild(AP4_ATOM_TYPE_TRAF, i));
AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, traf->GetChild(AP4_ATOM_TYPE_TFHD, i));
// create a sample table object so we can read the sample data
result = fragment->CreateSampleTable(moov, tfhd->GetTrackId(), &input, moof_offset, mdat_payload_offset, sample_table);
if (AP4_FAILED(result)) return result;
// compute the mdat size
AP4_UI64 mdat_size = 0;
for (unsigned int j=0; j<sample_table->GetSampleCount(); j++) {
result = sample_table->GetSample(j, sample);
if (AP4_FAILED(result)) return result;
mdat_size += sample.GetSize();
}
// write an mdat header
if (mdat_size > 0xFFFFFFFF-8) {
// we don't support large mdat fragments
return AP4_ERROR_OUT_OF_RANGE;
}
if (mdat_size) {
output.WriteUI32((AP4_UI32)(8+mdat_size));
output.WriteUI32(AP4_ATOM_TYPE_MDAT);
}
#if defined(AP4_DEBUG)
AP4_Position before;
output.Tell(before);
#endif
// write the mdat
for (unsigned int j=0; j<sample_table->GetSampleCount(); j++) {
result = sample_table->GetSample(j, sample);
if (AP4_FAILED(result)) return result;
sample.ReadData(sample_data_in);
// process the sample data
if (handler) {
result = handler->ProcessSample(sample_data_in, sample_data_out);
if (AP4_FAILED(result)) return result;
// write the sample data
result = output.Write(sample_data_out.GetData(), sample_data_out.GetDataSize());
if (AP4_FAILED(result)) return result;
// give the handler a chance to update the atoms
result = handler->FinishFragment();
if (AP4_SUCCEEDED(result)) moof_has_changed = true;
} else {
// write the sample data (unmodified)
result = output.Write(sample_data_in.GetData(), sample_data_in.GetDataSize());
if (AP4_FAILED(result)) return result;
}
}
//.........这里部分代码省略.........
示例12: Fragment
/*----------------------------------------------------------------------
| Fragment
+---------------------------------------------------------------------*/
static void
Fragment(AP4_File& input_file,
AP4_ByteStream& output_stream,
unsigned int fragment_duration,
AP4_UI32 timescale)
{
AP4_Result result;
AP4_Movie* input_movie = input_file.GetMovie();
if (input_movie == NULL) {
fprintf(stderr, "ERROR: no moov found in the input file\n");
return;
}
// create the output file object
AP4_Movie* output_movie = new AP4_Movie(1000);
// create an mvex container
AP4_ContainerAtom* mvex = new AP4_ContainerAtom(AP4_ATOM_TYPE_MVEX);
AP4_MehdAtom* mehd = new AP4_MehdAtom(0);
mvex->AddChild(mehd);
// create a cusor list to keep track of the tracks we will read from
AP4_Array<TrackCursor*> cursors;
// add an output track for each track in the input file
for (AP4_List<AP4_Track>::Item* track_item = input_movie->GetTracks().FirstItem();
track_item;
track_item = track_item->GetNext()) {
AP4_Track* track = track_item->GetData();
TrackCursor* cursor = new TrackCursor();
cursor->m_TrackId = track->GetId();
cursor->m_Tfra->SetTrackId(track->GetId());
cursors.Append(cursor);
// create a sample table (with no samples) to hold the sample description
AP4_SyntheticSampleTable* sample_table = new AP4_SyntheticSampleTable();
for (unsigned int i=0; i<track->GetSampleDescriptionCount(); i++) {
AP4_SampleDescription* sample_description = track->GetSampleDescription(i);
sample_table->AddSampleDescription(sample_description, false);
}
// create the track
AP4_Track* output_track = new AP4_Track(track->GetType(),
sample_table,
cursor->m_TrackId,
timescale?timescale:1000,
AP4_ConvertTime(track->GetDuration(),
input_movie->GetTimeScale(),
timescale?timescale:1000),
timescale?timescale:track->GetMediaTimeScale(),
0,//track->GetMediaDuration(),
track->GetTrackLanguage(),
track->GetWidth(),
track->GetHeight());
output_movie->AddTrack(output_track);
result = cursor->SetTrack(track);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: failed to read sample (%d)\n", result);
return;
}
// add a trex entry to the mvex container
AP4_TrexAtom* trex = new AP4_TrexAtom(cursor->m_TrackId,
1,
0,
0,
0);
mvex->AddChild(trex);
}
if (cursors.ItemCount() == 0) {
fprintf(stderr, "ERROR: no track found\n");
return;
}
for (unsigned int i=0; i<cursors.ItemCount(); i++) {
if (cursors[i]->m_Track->GetType() == AP4_Track::TYPE_VIDEO) {
cursors[i]->m_TargetDuration = AP4_ConvertTime(fragment_duration>AP4_FRAGMENTER_FRAGMENT_DURATION_TOLERANCE ?
fragment_duration-AP4_FRAGMENTER_FRAGMENT_DURATION_TOLERANCE : 0,
1000,
cursors[i]->m_Track->GetMediaTimeScale());
} else {
cursors[i]->m_TargetDuration = AP4_ConvertTime(fragment_duration,
1000,
cursors[i]->m_Track->GetMediaTimeScale());
}
}
// update the mehd duration
mehd->SetDuration(output_movie->GetDuration());
// the mvex container to the moov container
output_movie->GetMoovAtom()->AddChild(mvex);
// write the ftyp atom
AP4_FtypAtom* ftyp = input_file.GetFileType();
//.........这里部分代码省略.........
示例13: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| AP4_Processor::ProcessFragments
+---------------------------------------------------------------------*/
AP4_Result
AP4_Processor::ProcessFragment( AP4_ContainerAtom* moof,
AP4_SidxAtom* sidx,
AP4_Position sidx_position,
AP4_ByteStream& output,
AP4_Array<AP4_Position>& moof_positions,
AP4_Array<AP4_Position>& mdat_positions)
{
unsigned int fragment_index = 0;
//AP4_UI64 mdat_payload_offset = atom_offset+atom->GetSize()+AP4_ATOM_HEADER_SIZE;
AP4_Sample sample;
AP4_DataBuffer sample_data_in;
AP4_DataBuffer sample_data_out;
AP4_Result result = AP4_SUCCESS;
// parse the moof
//AP4_MovieFragment* fragment = new AP4_MovieFragment(moof);
// process all the traf atoms
AP4_Array<AP4_Processor::FragmentHandler*> handlers;
AP4_Array<AP4_FragmentSampleTable*> sample_tables;
for (; AP4_Atom* child = moof->GetChild(AP4_ATOM_TYPE_TRAF, handlers.ItemCount());) {
AP4_TrafAtom* traf = AP4_DYNAMIC_CAST(AP4_TrafAtom, child);
PERTRACK &track_data(m_TrackData[traf->GetInternalTrackId()]);
AP4_TrakAtom* trak = track_data.track_handler->GetTrakAtom();
AP4_TrexAtom* trex = track_data.track_handler->GetTrexAtom();
// create the handler for this traf
AP4_Processor::FragmentHandler* handler = CreateFragmentHandler(trak, trex, traf,
*(m_StreamData[track_data.streamId].stream),
moof_positions[track_data.streamId]);
if (handler) {
result = handler->ProcessFragment();
if (AP4_FAILED(result)) return result;
}
handlers.Append(handler);
// create a sample table object so we can read the sample data
AP4_FragmentSampleTable* sample_table = new AP4_FragmentSampleTable(
traf,
trex,
traf->GetInternalTrackId(),
m_StreamData[track_data.streamId].stream,
moof_positions[traf->GetInternalTrackId()],
mdat_positions[traf->GetInternalTrackId()],
0);
sample_tables.Append(sample_table);
// let the handler look at the samples before we process them
if (handler)
result = handler->PrepareForSamples(sample_table);
if (AP4_FAILED(result))
return result;
}
output.Buffer();
// write the moof
AP4_UI64 moof_out_start = 0;
output.Tell(moof_out_start);
moof->Write(output);
// remember the location of this fragment
FragmentMapEntry map_entry = { moof_positions[0], moof_out_start };
fragment_map_.Append(map_entry);
// write an mdat header
AP4_Position mdat_out_start;
AP4_UI64 mdat_size = AP4_ATOM_HEADER_SIZE;
output.Tell(mdat_out_start);
output.WriteUI32(0);
output.WriteUI32(AP4_ATOM_TYPE_MDAT);
// process all track runs
for (unsigned int i=0; i<handlers.ItemCount(); i++) {
AP4_Processor::FragmentHandler* handler = handlers[i];
// get the track ID
AP4_ContainerAtom* traf = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moof->GetChild(AP4_ATOM_TYPE_TRAF, i));
if (traf == NULL) continue;
AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, traf->GetChild(AP4_ATOM_TYPE_TFHD));
// compute the base data offset
AP4_UI64 base_data_offset;
if (tfhd->GetFlags() & AP4_TFHD_FLAG_BASE_DATA_OFFSET_PRESENT) {
base_data_offset = mdat_out_start+AP4_ATOM_HEADER_SIZE;
} else {
base_data_offset = moof_out_start;
}
// build a list of all trun atoms
AP4_Array<AP4_TrunAtom*> truns;
for (AP4_List<AP4_Atom>::Item* child_item = traf->GetChildren().FirstItem();
child_item;
//.........这里部分代码省略.........
示例14: 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);
//.........这里部分代码省略.........
示例15: 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);
//.........这里部分代码省略.........