本文整理汇总了C++中AP4_ContainerAtom::GetChild方法的典型用法代码示例。如果您正苦于以下问题:C++ AP4_ContainerAtom::GetChild方法的具体用法?C++ AP4_ContainerAtom::GetChild怎么用?C++ AP4_ContainerAtom::GetChild使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AP4_ContainerAtom
的用法示例。
在下文中一共展示了AP4_ContainerAtom::GetChild方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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;
}
示例2: if
/*----------------------------------------------------------------------
| AP4_CompactingProcessor::TrackHandler::ProcessTrack
+---------------------------------------------------------------------*/
AP4_Result
AP4_CompactingProcessor::TrackHandler::ProcessTrack()
{
// find the stsz atom
AP4_ContainerAtom* stbl = AP4_DYNAMIC_CAST(AP4_ContainerAtom, m_TrakAtom->FindChild("mdia/minf/stbl"));
if (stbl == NULL) return AP4_SUCCESS;
AP4_StszAtom* stsz = AP4_DYNAMIC_CAST(AP4_StszAtom, stbl->GetChild(AP4_ATOM_TYPE_STSZ));
if (stsz == NULL) return AP4_SUCCESS;
// check if we can reduce the size of stsz by changing it to stz2
AP4_UI32 max_size = 0;
for (unsigned int i=1; i<=stsz->GetSampleCount(); i++) {
AP4_Size sample_size;
stsz->GetSampleSize(i, sample_size);
if (sample_size > max_size) {
max_size = sample_size;
}
}
AP4_UI08 field_size = 0;
if (max_size <= 0xFF) {
field_size = 1;
} else if (max_size <= 0xFFFF) {
field_size = 2;
}
if (m_Outer.m_Verbose) printf("Track %d: ", m_TrakAtom->GetId());
if (field_size == 0) {
if (m_Outer.m_Verbose) {
printf("no stz2 reduction possible\n");
}
return AP4_SUCCESS;
} else {
if (m_Outer.m_Verbose) {
unsigned int reduction = (4-field_size)*stsz->GetSampleCount();
printf("stz2 reduction = %d bytes\n", reduction);
m_Outer.m_SizeReduction += reduction;
}
}
// detach the original stsz atom so we can destroy it later
m_StszAtom = stsz;
stsz->Detach();
// create an stz2 atom and populate its entries
AP4_Stz2Atom* stz2 = new AP4_Stz2Atom(field_size);
for (unsigned int i=1; i<=m_StszAtom->GetSampleCount(); i++) {
AP4_Size sample_size;
m_StszAtom->GetSampleSize(i, sample_size);
stz2->AddEntry(sample_size);
}
stbl->AddChild(stz2);
return AP4_SUCCESS;
}
示例3: switch
/*----------------------------------------------------------------------
| AP4_OmaDcfAtomDecrypter::CreateDecryptingStream
+---------------------------------------------------------------------*/
AP4_Result
AP4_OmaDcfAtomDecrypter::CreateDecryptingStream(
AP4_ContainerAtom& odrm,
const AP4_UI08* key,
AP4_Size key_size,
AP4_BlockCipherFactory* block_cipher_factory,
AP4_ByteStream*& stream)
{
// default return values
stream = NULL;
AP4_OdheAtom* odhe = AP4_DYNAMIC_CAST(AP4_OdheAtom, odrm.GetChild(AP4_ATOM_TYPE_ODHE));
if (odhe == NULL) return AP4_ERROR_INVALID_FORMAT;
AP4_OddaAtom* odda = AP4_DYNAMIC_CAST(AP4_OddaAtom, odrm.GetChild(AP4_ATOM_TYPE_ODDA));;
if (odda == NULL) return AP4_ERROR_INVALID_FORMAT;
AP4_OhdrAtom* ohdr = AP4_DYNAMIC_CAST(AP4_OhdrAtom, odhe->GetChild(AP4_ATOM_TYPE_OHDR));
if (ohdr == NULL) return AP4_ERROR_INVALID_FORMAT;
// default cipher factory
if (block_cipher_factory == NULL) {
block_cipher_factory = &AP4_DefaultBlockCipherFactory::Instance;
}
// shortcut for non-encrypted files
if (ohdr->GetEncryptionMethod() == AP4_OMA_DCF_ENCRYPTION_METHOD_NULL) {
stream = &odda->GetEncryptedPayload();
stream->AddReference();
return AP4_SUCCESS;
}
// if this is part of a group, use the group key to obtain the content
// key (note that the field called GroupKey in the spec is actually not
// the group key but the content key encrypted with the group key...
AP4_GrpiAtom* grpi = AP4_DYNAMIC_CAST(AP4_GrpiAtom, ohdr->GetChild(AP4_ATOM_TYPE_GRPI));
AP4_UI08* key_buffer = NULL;
if (grpi) {
// sanity check on the encrypted key size
if (grpi->GetGroupKey().GetDataSize() < 32) {
return AP4_ERROR_INVALID_FORMAT;
}
// create a block cipher to decrypt the content key
AP4_BlockCipher* block_cipher = NULL;
AP4_Result result;
// create a stream cipher from the block cipher
AP4_StreamCipher* stream_cipher = NULL;
switch (ohdr->GetEncryptionMethod()) {
case AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC:
result = block_cipher_factory->CreateCipher(AP4_BlockCipher::AES_128,
AP4_BlockCipher::DECRYPT,
AP4_BlockCipher::CBC,
NULL,
key,
key_size,
block_cipher);
if (AP4_FAILED(result)) return result;
stream_cipher = new AP4_CbcStreamCipher(block_cipher);
break;
case AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR: {
AP4_BlockCipher::CtrParams ctr_params;
ctr_params.counter_size = 16;
result = block_cipher_factory->CreateCipher(AP4_BlockCipher::AES_128,
AP4_BlockCipher::DECRYPT,
AP4_BlockCipher::CTR,
&ctr_params,
key,
key_size,
block_cipher);
if (AP4_FAILED(result)) return result;
stream_cipher = new AP4_CtrStreamCipher(block_cipher, 16);
break;
}
default:
return AP4_ERROR_NOT_SUPPORTED;
}
// set the IV
stream_cipher->SetIV(grpi->GetGroupKey().GetData());
// decrypt the content key
AP4_Size key_buffer_size = grpi->GetGroupKey().GetDataSize(); // worst case
key_buffer = new AP4_UI08[key_buffer_size];
result = stream_cipher->ProcessBuffer(grpi->GetGroupKey().GetData()+16,
grpi->GetGroupKey().GetDataSize()-16,
key_buffer,
&key_buffer_size,
true);
delete stream_cipher; // this will also delete the block cipher
if (AP4_FAILED(result)) {
delete[] key_buffer;
return result;
}
// point to the new key value
//.........这里部分代码省略.........
示例4: sizeof
/*----------------------------------------------------------------------
| DcfParser_ParseV2Header
+---------------------------------------------------------------------*/
static BLT_Result
DcfParser_ParseV2Header(DcfParser* self, ATX_InputStream* stream)
{
/* rewind the byte stream */
ATX_InputStream_Seek(stream, 0);
/* parse the atoms from the stream */
AP4_ByteStream* mp4_stream = new ATX_InputStream_To_AP4_ByteStream_Adapter(stream);
AP4_AtomParent atoms;
AP4_Result result = AP4_DefaultAtomFactory::Instance.CreateAtomsFromStream(*mp4_stream, atoms);
mp4_stream->Release();
AP4_ByteStream* decrypting_stream = NULL;
AP4_ContainerAtom* odrm = dynamic_cast<AP4_ContainerAtom*>(atoms.GetChild(AP4_ATOM_TYPE_ODRM));
if (odrm) {
AP4_OdheAtom* odhe = dynamic_cast<AP4_OdheAtom*>(odrm->GetChild(AP4_ATOM_TYPE_ODHE));
AP4_OddaAtom* odda = dynamic_cast<AP4_OddaAtom*>(odrm->GetChild(AP4_ATOM_TYPE_ODDA));
if (odhe && odda) {
const char* content_id = "";
/* get the content ID */
AP4_OhdrAtom* ohdr = dynamic_cast<AP4_OhdrAtom*>(odhe->GetChild(AP4_ATOM_TYPE_OHDR));
if (ohdr) {
content_id = ohdr->GetContentId().GetChars();
}
/* get the content key */
NPT_DataBuffer key;
result = DcfParser_GetContentKey(self, content_id, key);
if (BLT_FAILED(result)) {
ATX_LOG_FINE_2("GetKeyForContent(%s) returned %d",
content_id,
result);
return BLT_ERROR_NO_MEDIA_KEY;
}
/* create the decrypting stream */
result = AP4_OmaDcfAtomDecrypter::CreateDecryptingStream(*odrm,
key.GetData(),
key.GetDataSize(),
self->cipher_factory,
decrypting_stream);
if (AP4_SUCCEEDED(result)) {
/* update the content type */
ATX_CopyStringN(self->input.content_type,
odhe->GetContentType().GetChars(),
sizeof(self->input.content_type));
/* update the encrypted size */
self->input.encrypted_size = odda->GetEncryptedDataLength();
}
}
}
/* check that we have found what we needed in the atoms */
if (decrypting_stream == NULL) return BLT_ERROR_INVALID_MEDIA_FORMAT;
/* update the output size */
AP4_LargeSize plaintext_size = 0;
if (AP4_SUCCEEDED(decrypting_stream->GetSize(plaintext_size))) {
self->output.size = plaintext_size;
} else {
self->output.size = self->input.encrypted_size;
}
/* create a reverse adapter */
result = AP4_ByteStream_To_ATX_InputStream_Adapter_Create(decrypting_stream, &self->output.stream);
decrypting_stream->Release();
return BLT_SUCCESS;
}
示例5: if
/*----------------------------------------------------------------------
| AP4_MarlinIpmpDecryptingProcessor:CreateTrackHandler
+---------------------------------------------------------------------*/
AP4_Processor::TrackHandler*
AP4_MarlinIpmpDecryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak)
{
// look for this track in the list of entries
AP4_MarlinIpmpParser::SinfEntry* sinf_entry = NULL;
for (AP4_List<AP4_MarlinIpmpParser::SinfEntry>::Item* sinf_entry_item = m_SinfEntries.FirstItem();
sinf_entry_item;
sinf_entry_item = sinf_entry_item->GetNext()) {
sinf_entry = sinf_entry_item->GetData();
if (sinf_entry->m_TrackId == trak->GetId()) {
break; // match
} else {
sinf_entry = NULL; // no match
}
}
if (sinf_entry == NULL) return NULL; // no matching entry
AP4_ContainerAtom* sinf = sinf_entry->m_Sinf;
// check the scheme
bool use_group_key;
AP4_SchmAtom* schm = AP4_DYNAMIC_CAST(AP4_SchmAtom, sinf->GetChild(AP4_ATOM_TYPE_SCHM));
if (schm == NULL) return NULL; // no schm
if (schm->GetSchemeType() == AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACBC &&
schm->GetSchemeVersion() == 0x0100) {
use_group_key = false;
} else if (schm->GetSchemeType() == AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACGK &&
schm->GetSchemeVersion() == 0x0100) {
use_group_key = true;
} else {
// unsupported scheme
return NULL;
}
// find the key
const AP4_DataBuffer* key = NULL;
AP4_DataBuffer unwrapped_key;
if (use_group_key) {
const AP4_DataBuffer* group_key = m_KeyMap.GetKey(0);
if (group_key == NULL) return NULL; // no group key
AP4_ContainerAtom* schi = AP4_DYNAMIC_CAST(AP4_ContainerAtom, sinf->GetChild(AP4_ATOM_TYPE_SCHI));
if (schi == NULL) return NULL; // no schi
AP4_Atom* gkey = schi->GetChild(AP4_ATOM_TYPE_GKEY);
if (gkey == NULL) return NULL; // no gkey
AP4_MemoryByteStream* gkey_data = new AP4_MemoryByteStream();
gkey->WriteFields(*gkey_data);
AP4_AesKeyUnwrap(group_key->GetData(), gkey_data->GetData(), gkey_data->GetDataSize(), unwrapped_key);
key = &unwrapped_key;
gkey_data->Release();
} else {
key = m_KeyMap.GetKey(sinf_entry->m_TrackId);
}
if (key == NULL) return NULL;
// create the decrypter
AP4_MarlinIpmpTrackDecrypter* decrypter = NULL;
AP4_Result result = AP4_MarlinIpmpTrackDecrypter::Create(*m_BlockCipherFactory,
key->GetData(),
key->GetDataSize(),
decrypter);
if (AP4_FAILED(result)) return NULL;
return decrypter;
}
示例6: if
/*----------------------------------------------------------------------
| 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;
//.........这里部分代码省略.........
示例7: CreateFragmentHandler
/*----------------------------------------------------------------------
| 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;
//.........这里部分代码省略.........
示例8: if
/*----------------------------------------------------------------------
| 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);
//.........这里部分代码省略.........
示例9: PrintUsageAndExit
//.........这里部分代码省略.........
if (track == NULL) {
fprintf(stderr, "--video option specified, but no video track found\n");
return 1;
}
Options.track_filter = track->GetId();
} 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)) {
示例10: GetTrack
/*----------------------------------------------------------------------
| 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);
}
}
}
}
}
}
}
}
}
示例11: CreateFragmentHandler
/*----------------------------------------------------------------------
| 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;
}
}
//.........这里部分代码省略.........