本文整理汇总了C++中AP4_Atom类的典型用法代码示例。如果您正苦于以下问题:C++ AP4_Atom类的具体用法?C++ AP4_Atom怎么用?C++ AP4_Atom使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AP4_Atom类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: AP4_ContainerAtom
/*----------------------------------------------------------------------
| AP4_StsdAtom::AP4_StsdAtom
+---------------------------------------------------------------------*/
AP4_StsdAtom::AP4_StsdAtom(AP4_Size size,
AP4_ByteStream& stream,
AP4_AtomFactory& atom_factory) :
AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, size, true, stream)
{
// read the number of entries
AP4_UI32 entry_count;
stream.ReadUI32(entry_count);
// read all entries
AP4_Size bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4;
m_Data.SetDataSize(bytes_available);
stream.Read(m_Data.UseData(), m_Data.GetDataSize());
AP4_ByteStream* s = DNew AP4_MemoryByteStream(m_Data.UseData(), m_Data.GetDataSize());
for (unsigned int i=0; i<entry_count; i++) {
AP4_Atom* atom;
if (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(*s,
bytes_available,
atom,
this))) {
atom->SetParent(this);
m_Children.Add(atom);
}
}
s->Release();
// initialize the sample description cache
m_SampleDescriptions.EnsureCapacity(m_Children.ItemCount());
for (AP4_Ordinal i=0; i<m_Children.ItemCount(); i++) {
m_SampleDescriptions.Append(NULL);
}
}
示例2: m_Movie
/*----------------------------------------------------------------------
| AP4_File::AP4_File
+---------------------------------------------------------------------*/
AP4_File::AP4_File(AP4_ByteStream& stream, AP4_AtomFactory& atom_factory) :
m_Movie(NULL)
{
// get all atoms
AP4_Atom* atom;
while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, atom))) {
switch (atom->GetType()) {
case AP4_ATOM_TYPE_MOOV:
m_Movie = new AP4_Movie(dynamic_cast<AP4_MoovAtom*>(atom),
stream);
break;
case AP4_ATOM_TYPE_MOOF:
if (m_Movie) {
m_Movie->ProcessMoof(AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom),
stream);
}
delete atom;
break;
case AP4_ATOM_TYPE_FTYP:
//m_Movie = new AP4_Movie(dynamic_cast<AP4_FtypAtom*>(atom), stream);
m_FileType = dynamic_cast<AP4_FtypAtom*>(atom);
default:
m_OtherAtoms.Add(atom);
}
}
}
示例3: m_Movie
/*----------------------------------------------------------------------
| AP4_File::AP4_File
+---------------------------------------------------------------------*/
AP4_File::AP4_File(AP4_ByteStream& stream,
AP4_AtomFactory& atom_factory,
bool moov_only) :
m_Movie(NULL),
m_FileType(NULL),
m_MetaData(NULL),
m_MoovIsBeforeMdat(true)
{
// parse top-level atoms
AP4_Atom* atom;
AP4_Position stream_position;
bool keep_parsing = true;
while (keep_parsing &&
AP4_SUCCEEDED(stream.Tell(stream_position)) &&
AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, atom))) {
AddChild(atom);
switch (atom->GetType()) {
case AP4_ATOM_TYPE_MOOV:
m_Movie = new AP4_Movie(AP4_DYNAMIC_CAST(AP4_MoovAtom, atom), stream, false);
if (moov_only) keep_parsing = false;
break;
case AP4_ATOM_TYPE_FTYP:
m_FileType = AP4_DYNAMIC_CAST(AP4_FtypAtom, atom);
break;
case AP4_ATOM_TYPE_MDAT:
// see if we are before the moov atom
if (m_Movie == NULL) m_MoovIsBeforeMdat = false;
break;
}
}
}
示例4: AP4_ContainerAtom
/*----------------------------------------------------------------------
| AP4_StsdAtom::AP4_StsdAtom
+---------------------------------------------------------------------*/
AP4_StsdAtom::AP4_StsdAtom(AP4_UI32 size,
AP4_UI08 version,
AP4_UI32 flags,
AP4_ByteStream& stream,
AP4_AtomFactory& atom_factory) :
AP4_ContainerAtom(AP4_ATOM_TYPE_STSD, size, false, version, flags)
{
// read the number of entries
AP4_UI32 entry_count;
stream.ReadUI32(entry_count);
// save and switch the factory's context
atom_factory.PushContext(m_Type);
// read all entries
AP4_LargeSize bytes_available = size-AP4_FULL_ATOM_HEADER_SIZE-4;
for (unsigned int i=0; i<entry_count; i++) {
AP4_Atom* atom;
if (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream,
bytes_available,
atom))) {
atom->SetParent(this);
m_Children.Add(atom);
}
}
// restore the saved context
atom_factory.PopContext();
// initialize the sample description cache
m_SampleDescriptions.EnsureCapacity(m_Children.ItemCount());
for (AP4_Ordinal i=0; i<m_Children.ItemCount(); i++) {
m_SampleDescriptions.Append(NULL);
}
}
示例5: assert
/*----------------------------------------------------------------------
| AP4_LinearReader::AdvanceFragment
+---------------------------------------------------------------------*/
AP4_Result
AP4_LinearReader::AdvanceFragment()
{
AP4_Result result;
// go the the start of the next fragment
result = m_FragmentStream->Seek(m_NextFragmentPosition);
if (AP4_FAILED(result)) return result;
// read atoms until we find a moof
assert(m_HasFragments);
if (!m_FragmentStream) return AP4_ERROR_INVALID_STATE;
do {
AP4_Atom* atom = NULL;
result = AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(*m_FragmentStream, atom);
if (AP4_SUCCEEDED(result)) {
if (atom->GetType() == AP4_ATOM_TYPE_MOOF) {
AP4_ContainerAtom* moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
if (moof) {
// remember where we are in the stream
AP4_Position position = 0;
m_FragmentStream->Tell(position);
// process the movie fragment
result = ProcessMoof(moof, position-atom->GetSize(), position+8);
if (AP4_FAILED(result)) return result;
// compute where the next fragment will be
AP4_UI32 size;
AP4_UI32 type;
m_FragmentStream->Tell(position);
result = m_FragmentStream->ReadUI32(size);
if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more
result = m_FragmentStream->ReadUI32(type);
if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more
if (size == 0) {
m_NextFragmentPosition = 0;
} else if (size == 1) {
AP4_UI64 size_64 = 0;
result = m_FragmentStream->ReadUI64(size_64);
if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more
m_NextFragmentPosition = position+size_64;
} else {
m_NextFragmentPosition = position+size;
}
return AP4_SUCCESS;
} else {
delete atom;
}
} else {
delete atom;
}
}
} while (AP4_SUCCEEDED(result));
return AP4_ERROR_EOS;
}
示例6: CreateDecryptingStream
/*----------------------------------------------------------------------
| AP4_OmaDcfAtomDecrypter::DecryptAtoms
+---------------------------------------------------------------------*/
AP4_Result
AP4_OmaDcfAtomDecrypter::DecryptAtoms(AP4_AtomParent& atoms,
AP4_Processor::ProgressListener* /*listener*/,
AP4_BlockCipherFactory* block_cipher_factory,
AP4_ProtectionKeyMap& key_map)
{
// default factory
if (block_cipher_factory == NULL) {
block_cipher_factory = &AP4_DefaultBlockCipherFactory::Instance;
}
unsigned int index = 1;
for (AP4_List<AP4_Atom>::Item* item = atoms.GetChildren().FirstItem();
item;
item = item->GetNext()) {
AP4_Atom* atom = item->GetData();
if (atom->GetType() != AP4_ATOM_TYPE_ODRM) continue;
// check that we have the key
const AP4_DataBuffer* key = key_map.GetKey(index++);
if (key == NULL) return AP4_ERROR_INVALID_PARAMETERS;
// check that we have all the atoms we need
AP4_ContainerAtom* odrm = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
if (odrm == NULL) continue; // not enough info
AP4_OdheAtom* odhe = AP4_DYNAMIC_CAST(AP4_OdheAtom, odrm->GetChild(AP4_ATOM_TYPE_ODHE));
if (odhe == NULL) continue; // not enough info
AP4_OddaAtom* odda = AP4_DYNAMIC_CAST(AP4_OddaAtom, odrm->GetChild(AP4_ATOM_TYPE_ODDA));;
if (odda == NULL) continue; // not enough info
AP4_OhdrAtom* ohdr = AP4_DYNAMIC_CAST(AP4_OhdrAtom, odhe->GetChild(AP4_ATOM_TYPE_OHDR));
if (ohdr == NULL) continue; // not enough info
// do nothing if the atom is not encrypted
if (ohdr->GetEncryptionMethod() == AP4_OMA_DCF_ENCRYPTION_METHOD_NULL) {
continue;
}
// create the byte stream
AP4_ByteStream* cipher_stream = NULL;
AP4_Result result = CreateDecryptingStream(*odrm,
key->GetData(),
key->GetDataSize(),
block_cipher_factory,
cipher_stream);
if (AP4_SUCCEEDED(result)) {
// replace the odda atom's payload with the decrypted stream
odda->SetEncryptedPayload(*cipher_stream, ohdr->GetPlaintextLength());
cipher_stream->Release();
// the atom will now be in the clear
ohdr->SetEncryptionMethod(AP4_OMA_DCF_ENCRYPTION_METHOD_NULL);
ohdr->SetPaddingScheme(AP4_OMA_DCF_PADDING_SCHEME_NONE);
}
}
return AP4_SUCCESS;
}
示例7: while
/*----------------------------------------------------------------------
| AP4_ContainerAtom::ReadChildren
+---------------------------------------------------------------------*/
void
AP4_ContainerAtom::ReadChildren(AP4_AtomFactory& atom_factory,
AP4_ByteStream& stream,
AP4_Size size)
{
AP4_Atom* atom;
AP4_Size bytes_available = size;
while (AP4_SUCCEEDED(
atom_factory.CreateAtomFromStream(stream, bytes_available, atom, this))) {
atom->SetParent(this);
m_Children.Add(atom);
}
}
示例8: main
/*----------------------------------------------------------------------
| main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
if (argc != 2) {
PrintUsageAndExit();
}
const char* input_filename = argv[1];
// open the input
AP4_ByteStream* input = NULL;
AP4_Result result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename);
return 1;
}
// get the movie
AP4_File* file = new AP4_File(*input, AP4_DefaultAtomFactory::Instance, true);
AP4_Movie* movie = file->GetMovie();
AP4_Atom* atom = NULL;
do {
// process the next atom
result = AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(*input, atom);
if (AP4_SUCCEEDED(result)) {
printf("atom size=%lld\n", atom->GetSize());
if (atom->GetType() == AP4_ATOM_TYPE_MOOF) {
AP4_ContainerAtom* moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
if (moof) {
// remember where we are in the stream
AP4_Position position = 0;
input->Tell(position);
// process the movie fragment
ProcessMoof(movie, moof, input, position-atom->GetSize(), position+8);
// go back to where we were before processing the fragment
input->Seek(position);
}
} else {
delete atom;
}
}
} while (AP4_SUCCEEDED(result));
// cleanup
delete file;
input->Release();
return 0;
}
示例9: AutoDetectAudioFragmentDuration
/*----------------------------------------------------------------------
| AutoDetectAudioFragmentDuration
+---------------------------------------------------------------------*/
static unsigned int
AutoDetectAudioFragmentDuration(AP4_ByteStream& stream, TrackCursor* cursor)
{
// remember where we are in the stream
AP4_Position where = 0;
stream.Tell(where);
AP4_LargeSize stream_size = 0;
stream.GetSize(stream_size);
AP4_LargeSize bytes_available = stream_size-where;
AP4_UI64 fragment_count = 0;
AP4_UI32 last_fragment_size = 0;
AP4_Atom* atom = NULL;
while (AP4_SUCCEEDED(AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(stream, bytes_available, atom))) {
if (atom && atom->GetType() == AP4_ATOM_TYPE_MOOF) {
AP4_ContainerAtom* moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, moof->FindChild("traf/tfhd"));
if (tfhd && tfhd->GetTrackId() == cursor->m_Track->GetId()) {
++fragment_count;
AP4_TrunAtom* trun = AP4_DYNAMIC_CAST(AP4_TrunAtom, moof->FindChild("traf/trun"));
if (trun) {
last_fragment_size = trun->GetEntries().ItemCount();
}
}
}
delete atom;
atom = NULL;
}
// restore the stream to its original position
stream.Seek(where);
// decide if we can infer an fragment size
if (fragment_count == 0 || cursor->m_Samples->GetSampleCount() == 0) {
return 0;
}
// don't count the last fragment if we have more than one
if (fragment_count > 1 && last_fragment_size) {
--fragment_count;
}
if (fragment_count <= 1 || cursor->m_Samples->GetSampleCount() < last_fragment_size) {
last_fragment_size = 0;
}
AP4_Sample sample;
AP4_UI64 total_duration = 0;
for (unsigned int i=0; i<cursor->m_Samples->GetSampleCount()-last_fragment_size; i++) {
cursor->m_Samples->GetSample(i, sample);
total_duration += sample.GetDuration();
}
return (unsigned int)AP4_ConvertTime(total_duration/fragment_count, cursor->m_Track->GetMediaTimeScale(), 1000);
}
示例10: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| AP4_FragmentSampleTable::AP4_FragmentSampleTable
+---------------------------------------------------------------------*/
AP4_FragmentSampleTable::AP4_FragmentSampleTable(AP4_ContainerAtom* traf,
AP4_TrexAtom* trex,
AP4_Cardinal internal_track_id,
AP4_ByteStream* sample_stream,
AP4_Position moof_offset,
AP4_Position mdat_payload_offset,
AP4_UI64 dts_origin)
:m_InternalTrackId(internal_track_id)
{
AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, traf->GetChild(AP4_ATOM_TYPE_TFHD));
if (tfhd == NULL) return;
// count all the samples and reserve space for them
unsigned int sample_count = 0;
for (AP4_List<AP4_Atom>::Item* item = traf->GetChildren().FirstItem();
item;
item = item->GetNext()) {
AP4_Atom* atom = item->GetData();
if (atom->GetType() == AP4_ATOM_TYPE_TRUN) {
AP4_TrunAtom* trun = AP4_DYNAMIC_CAST(AP4_TrunAtom, atom);
if (trun) sample_count += trun->GetEntries().ItemCount();
}
}
m_Samples.EnsureCapacity(sample_count);
// check if we have a timecode base
AP4_TfdtAtom* tfdt = AP4_DYNAMIC_CAST(AP4_TfdtAtom, traf->GetChild(AP4_ATOM_TYPE_TFDT));
if (tfdt) {
dts_origin = tfdt->GetBaseMediaDecodeTime();
}
// process all the trun atoms
for (AP4_List<AP4_Atom>::Item* item = traf->GetChildren().FirstItem();
item;
item = item->GetNext()) {
AP4_Atom* atom = item->GetData();
if (atom->GetType() == AP4_ATOM_TYPE_TRUN) {
AP4_TrunAtom* trun = AP4_DYNAMIC_CAST(AP4_TrunAtom, atom);
if (trun) {
AP4_Result result = AddTrun(trun,
tfhd,
trex,
sample_stream,
moof_offset,
mdat_payload_offset,
dts_origin);
if (AP4_FAILED(result)) return;
}
}
}
}
示例11: m_Movie
/*----------------------------------------------------------------------
| AP4_File::AP4_File
+---------------------------------------------------------------------*/
AP4_File::AP4_File(AP4_ByteStream& stream, AP4_AtomFactory& atom_factory) :
m_Movie(NULL)
{
// get all atoms
AP4_Atom* atom;
while (AP4_SUCCEEDED(atom_factory.CreateAtomFromStream(stream, atom))) {
switch (atom->GetType()) {
case AP4_ATOM_TYPE_MOOV:
case AP4_ATOM_TYPE_3DVF:
m_Movie = DNew AP4_Movie(dynamic_cast<AP4_MoovAtom*>(atom),
stream);
break;
case AP4_ATOM_TYPE_FTYP:
//m_Movie = DNew AP4_Movie(dynamic_cast<AP4_FtypAtom*>(atom), stream);
m_FileType = dynamic_cast<AP4_FtypAtom*>(atom);
default:
m_OtherAtoms.Add(atom);
}
}
}
示例12: Mp4ParserOutput_SetSampleDescription
/*----------------------------------------------------------------------
| Mp4ParserOutput_SetSampleDescription
+---------------------------------------------------------------------*/
static BLT_Result
Mp4ParserOutput_SetSampleDescription(Mp4ParserOutput* self,
unsigned int indx)
{
// if we had a decrypter before, release it now
delete self->sample_decrypter;
self->sample_decrypter = NULL;
// check that the audio track is of the right type
AP4_SampleDescription* sample_desc = self->track->GetSampleDescription(indx);
if (sample_desc == NULL) {
ATX_LOG_FINE("no sample description for track");
return BLT_ERROR_INVALID_MEDIA_FORMAT;
}
// handle encrypted tracks
BLT_Result result = Mp4ParserOutput_ProcessCryptoInfo(self, sample_desc);
if (BLT_FAILED(result)) return result;
// update the generic part of the stream info
BLT_StreamInfo stream_info;
stream_info.id = self->track->GetId();
stream_info.duration = self->track->GetDurationMs();
stream_info.mask = BLT_STREAM_INFO_MASK_ID |
BLT_STREAM_INFO_MASK_DURATION;
// deal with audio details, if this is an audio track
AP4_AudioSampleDescription* audio_desc = dynamic_cast<AP4_AudioSampleDescription*>(sample_desc);
if (audio_desc) {
ATX_LOG_FINE("sample description is audio");
stream_info.type = BLT_STREAM_TYPE_AUDIO;
stream_info.channel_count = audio_desc->GetChannelCount();
stream_info.sample_rate = audio_desc->GetSampleRate();
stream_info.mask |= BLT_STREAM_INFO_MASK_TYPE |
BLT_STREAM_INFO_MASK_CHANNEL_COUNT |
BLT_STREAM_INFO_MASK_SAMPLE_RATE;
} else if (self == &self->parser->audio_output) {
ATX_LOG_FINE("expected audio sample description, but did not get one");
return BLT_ERROR_INVALID_MEDIA_FORMAT;
}
AP4_VideoSampleDescription* video_desc = dynamic_cast<AP4_VideoSampleDescription*>(sample_desc);
if (video_desc) {
ATX_LOG_FINE("sample description is video");
stream_info.type = BLT_STREAM_TYPE_VIDEO;
stream_info.width = video_desc->GetWidth();
stream_info.height = video_desc->GetHeight();
stream_info.mask |= BLT_STREAM_INFO_MASK_TYPE |
BLT_STREAM_INFO_MASK_WIDTH |
BLT_STREAM_INFO_MASK_HEIGHT;
} else if (self == &self->parser->video_output) {
ATX_LOG_FINE("expected video sample descriton, but did not get one");
return BLT_ERROR_INVALID_MEDIA_FORMAT;
}
AP4_MpegSampleDescription* mpeg_desc = NULL;
if (sample_desc->GetType() == AP4_SampleDescription::TYPE_MPEG) {
ATX_LOG_FINE("sample description is of type MPEG");
mpeg_desc = dynamic_cast<AP4_MpegSampleDescription*>(sample_desc);
}
if (mpeg_desc) {
stream_info.data_type = mpeg_desc->GetObjectTypeString(mpeg_desc->GetObjectTypeId());
stream_info.average_bitrate = mpeg_desc->GetAvgBitrate();
stream_info.nominal_bitrate = mpeg_desc->GetAvgBitrate();
stream_info.mask |= BLT_STREAM_INFO_MASK_AVERAGE_BITRATE |
BLT_STREAM_INFO_MASK_NOMINAL_BITRATE |
BLT_STREAM_INFO_MASK_DATA_TYPE;
}
// setup the output media type
AP4_DataBuffer decoder_info;
BLT_MediaTypeId media_type_id = BLT_MEDIA_TYPE_ID_NONE;
AP4_UI32 format_or_object_type_id = 0;
if (mpeg_desc) {
decoder_info.SetData(mpeg_desc->GetDecoderInfo().GetData(),
mpeg_desc->GetDecoderInfo().GetDataSize());
media_type_id = self->mp4_es_type_id;
format_or_object_type_id = mpeg_desc->GetObjectTypeId();
} else {
// here we have to be format-specific for the decoder info
stream_info.data_type = AP4_GetFormatName(sample_desc->GetFormat());
stream_info.mask |= BLT_STREAM_INFO_MASK_DATA_TYPE;
format_or_object_type_id = sample_desc->GetFormat();
if (sample_desc->GetFormat() == AP4_SAMPLE_FORMAT_AVC1) {
// look for an 'avcC' atom
AP4_AvccAtom* avcc = static_cast<AP4_AvccAtom*>(sample_desc->GetDetails().GetChild(AP4_ATOM_TYPE_AVCC));
if (avcc) {
// pass the avcc payload as the decoder info
decoder_info.SetData(avcc->GetRawBytes().GetData(),
avcc->GetRawBytes().GetDataSize());
}
} else if (sample_desc->GetFormat() == AP4_SAMPLE_FORMAT_ALAC) {
// look for an 'alac' atom (either top-level or inside a 'wave')
AP4_Atom* alac = sample_desc->GetDetails().GetChild(AP4_SAMPLE_FORMAT_ALAC);
if (alac == NULL) {
AP4_ContainerAtom* wave = dynamic_cast<AP4_ContainerAtom*>(sample_desc->GetDetails().GetChild(AP4_ATOM_TYPE_WAVE));
if (wave) {
alac = wave->GetChild(AP4_SAMPLE_FORMAT_ALAC);
//.........这里部分代码省略.........
示例13: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| AP4_Movie::ProcessMoof
+---------------------------------------------------------------------*/
void
AP4_Movie::ProcessMoof(AP4_ContainerAtom* moof, AP4_ByteStream& stream)
{
if (moof) {
AP4_Offset offset = 0;
stream.Tell(offset);
AP4_Offset moof_offset = offset - moof->GetSize();
AP4_Offset mdat_payload_offset = offset + 8;
AP4_MfhdAtom* mfhd = AP4_DYNAMIC_CAST(AP4_MfhdAtom, moof->GetChild(AP4_ATOM_TYPE_MFHD));
if (mfhd) {
for (AP4_List<AP4_Atom>::Item* item = moof->GetChildren().FirstItem();
item;
item = item->GetNext()) {
AP4_Atom* atom = item->GetData();
if (atom->GetType() == AP4_ATOM_TYPE_TRAF) {
AP4_ContainerAtom* traf = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom);
if (traf) {
AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, traf->GetChild(AP4_ATOM_TYPE_TFHD));
if (!tfhd) {
continue;
}
AP4_Track* track = GetTrack(tfhd->GetTrackId());
if (!track) {
continue;
}
AP4_TfdtAtom* tfdt = AP4_DYNAMIC_CAST(AP4_TfdtAtom, traf->GetChild(AP4_ATOM_TYPE_TFDT));
AP4_TrexAtom* trex = NULL;
AP4_ContainerAtom* mvex = AP4_DYNAMIC_CAST(AP4_ContainerAtom, m_MoovAtom->GetChild(AP4_ATOM_TYPE_MVEX));
if (mvex) {
for (AP4_List<AP4_Atom>::Item* child_item = mvex->GetChildren().FirstItem();
child_item;
child_item = child_item->GetNext()) {
AP4_Atom* child_atom = child_item->GetData();
if (child_atom->GetType() == AP4_ATOM_TYPE_TREX) {
trex = AP4_DYNAMIC_CAST(AP4_TrexAtom, child_atom);
if (trex && trex->GetTrackId() == tfhd->GetTrackId()) break;
trex = NULL;
}
}
}
AP4_FragmentSampleTable* sampleTable = track->GetFragmentSampleTable();
AP4_Cardinal sample_count = 0;
for (AP4_List<AP4_Atom>::Item* child_item = traf->GetChildren().FirstItem();
child_item;
child_item = child_item->GetNext()) {
AP4_Atom* child_atom = child_item->GetData();
if (child_atom->GetType() == AP4_ATOM_TYPE_TRUN) {
AP4_TrunAtom* trun = AP4_DYNAMIC_CAST(AP4_TrunAtom, child_atom);
if (trun) {
sample_count += trun->GetEntries().ItemCount();
}
}
}
if (!sample_count) {
return;
}
if (sampleTable->GetSampleCount() == 0) {
track->CreateFragmentFromStdSamples();
}
if (AP4_FAILED(sampleTable->EnsureCapacity(sample_count + sampleTable->GetSampleCount()))) {
return;
}
AP4_UI64 dts_origin = tfdt ? tfdt->GetBaseMediaDecodeTime() : 0;
for (AP4_List<AP4_Atom>::Item* child_item = traf->GetChildren().FirstItem();
child_item;
child_item = child_item->GetNext()) {
AP4_Atom* child_atom = child_item->GetData();
if (child_atom->GetType() == AP4_ATOM_TYPE_TRUN) {
AP4_TrunAtom* trun = AP4_DYNAMIC_CAST(AP4_TrunAtom, child_atom);
if (trun) {
sampleTable->AddTrun(trun, tfhd, trex, stream, dts_origin, moof_offset, mdat_payload_offset);
}
}
}
}
}
}
}
}
}
示例14: main
/*----------------------------------------------------------------------
| main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
if (argc < 4) {
PrintUsageAndExit();
}
// parse arguments
const char* atom_path = NULL;
const char* input_filename = NULL;
const char* output_filename = NULL;
bool payload_only = false;
char* arg;
while ((arg = *++argv)) {
if (!strcmp(arg, "--payload-only")) {
payload_only = true;
} else if (atom_path == NULL) {
atom_path = arg;
} else if (input_filename == NULL) {
input_filename = arg;
} else if (output_filename == NULL) {
output_filename = arg;
} else {
fprintf(stderr, "ERROR: invalid command line argument (%s)\n", arg);
return 1;
}
}
// check arguments
if (atom_path == NULL) {
fprintf(stderr, "ERROR: missing atom path\n");
return 1;
}
if (input_filename == NULL) {
fprintf(stderr, "ERROR: missing input filename\n");
return 1;
}
if (output_filename == NULL) {
fprintf(stderr, "ERROR: missing output filename\n");
return 1;
}
// create the input stream
AP4_Result result;
AP4_ByteStream* input = NULL;
result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename);
return 1;
}
// parse the atoms
AP4_AtomParent top_level;
AP4_Atom* atom;
AP4_AtomFactory& atom_factory = AP4_DefaultAtomFactory::Instance;
while (atom_factory.CreateAtomFromStream(*input, atom) == AP4_SUCCESS) {
top_level.AddChild(atom);
}
// release the input
input->Release();
// find the atom
atom = top_level.FindChild(atom_path);
if (atom == NULL) {
fprintf(stderr, "ERROR: atom '%s' not found\n", atom_path);
return 1;
}
// create the output stream
AP4_ByteStream* output = NULL;
result = AP4_FileByteStream::Create(output_filename, AP4_FileByteStream::STREAM_MODE_WRITE, output);
if (AP4_FAILED(result)) {
fprintf(stderr, "ERROR: cannot open output file (%s)\n", output_filename);
return 1;
}
// write the atom
if (payload_only) {
atom->WriteFields(*output);
} else {
atom->Write(*output);
}
// cleanup
output->Release();
return 0;
}
示例15: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| AP4_MarlinIpmpParser:Parse
+---------------------------------------------------------------------*/
AP4_Result
AP4_MarlinIpmpParser::Parse(AP4_AtomParent& top_level,
AP4_ByteStream& stream,
AP4_List<SinfEntry>& sinf_entries,
bool remove_od_data)
{
// check the file type
AP4_FtypAtom* ftyp = AP4_DYNAMIC_CAST(AP4_FtypAtom, top_level.GetChild(AP4_ATOM_TYPE_FTYP));
if (ftyp == NULL ||
(ftyp->GetMajorBrand() != AP4_MARLIN_BRAND_MGSV && !ftyp->HasCompatibleBrand(AP4_MARLIN_BRAND_MGSV))) {
return AP4_ERROR_INVALID_FORMAT;
}
// check the initial object descriptor and get the OD Track ID
AP4_IodsAtom* iods = AP4_DYNAMIC_CAST(AP4_IodsAtom, top_level.FindChild("moov/iods"));
AP4_UI32 od_track_id = 0;
if (iods == NULL) return AP4_ERROR_INVALID_FORMAT;
const AP4_ObjectDescriptor* od = iods->GetObjectDescriptor();
if (od == NULL) return AP4_ERROR_INVALID_FORMAT;
AP4_EsIdIncDescriptor* es_id_inc = AP4_DYNAMIC_CAST(AP4_EsIdIncDescriptor, od->FindSubDescriptor(AP4_DESCRIPTOR_TAG_ES_ID_INC));
if (es_id_inc == NULL) return AP4_ERROR_INVALID_FORMAT;
od_track_id = es_id_inc->GetTrackId();
// find the track pointed to by the descriptor
AP4_MoovAtom* moov = AP4_DYNAMIC_CAST(AP4_MoovAtom, top_level.GetChild(AP4_ATOM_TYPE_MOOV));
if (moov == NULL) return AP4_ERROR_INVALID_FORMAT;
AP4_TrakAtom* od_trak = NULL;
AP4_List<AP4_TrakAtom>::Item* trak_item = moov->GetTrakAtoms().FirstItem();
while (trak_item) {
AP4_TrakAtom* trak = trak_item->GetData();
if (trak) {
if (trak->GetId() == od_track_id) {
od_trak = trak;
} else {
sinf_entries.Add(new SinfEntry(trak->GetId(), NULL));
}
}
trak_item = trak_item->GetNext();
}
// check that we have found the OD track
if (od_trak == NULL) return AP4_ERROR_INVALID_FORMAT;
// look for the 'mpod' trak references
AP4_TrefTypeAtom* track_references;
track_references = AP4_DYNAMIC_CAST(AP4_TrefTypeAtom, od_trak->FindChild("tref/mpod"));
if (track_references == NULL) return AP4_ERROR_INVALID_FORMAT;
// create an AP4_Track object from the trak atom and check that it has samples
AP4_Track* od_track = new AP4_Track(*od_trak, stream, 0);
if (od_track->GetSampleCount() < 1) {
delete od_track;
return AP4_ERROR_INVALID_FORMAT;
}
// get the first sample (in this version, we only look at a single OD command)
AP4_Sample od_sample;
AP4_Result result = od_track->GetSample(0, od_sample);
if (AP4_FAILED(result)) {
delete od_track;
return AP4_ERROR_INVALID_FORMAT;
}
// adapt the sample data into a byte stream for parsing
AP4_DataBuffer sample_data;
od_sample.ReadData(sample_data);
AP4_MemoryByteStream* sample_stream = new AP4_MemoryByteStream(sample_data);
// look for one ObjectDescriptorUpdate command and
// one IPMP_DescriptorUpdate command
AP4_DescriptorUpdateCommand* od_update = NULL;
AP4_DescriptorUpdateCommand* ipmp_update = NULL;
do {
AP4_Command* command = NULL;
result = AP4_CommandFactory::CreateCommandFromStream(*sample_stream, command);
if (AP4_SUCCEEDED(result)) {
// found a command in the sample, check the type
switch (command->GetTag()) {
case AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE:
if (od_update == NULL) {
od_update = AP4_DYNAMIC_CAST(AP4_DescriptorUpdateCommand, command);
}
break;
case AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE:
if (ipmp_update == NULL) {
ipmp_update = AP4_DYNAMIC_CAST(AP4_DescriptorUpdateCommand, command);
}
break;
default:
break;
}
}
} while (AP4_SUCCEEDED(result));
sample_stream->Release();
sample_stream = NULL;
//.........这里部分代码省略.........