本文整理汇总了C++中AP4_ContainerAtom类的典型用法代码示例。如果您正苦于以下问题:C++ AP4_ContainerAtom类的具体用法?C++ AP4_ContainerAtom怎么用?C++ AP4_ContainerAtom使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AP4_ContainerAtom类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: AP4_ContainerAtom
/*----------------------------------------------------------------------
| AP4_IsmaTrackEncrypter::ProcessTrack
+---------------------------------------------------------------------*/
AP4_Result
AP4_IsmaTrackEncrypter::ProcessTrack()
{
// sinf container
AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF);
// original format
AP4_FrmaAtom* frma = new AP4_FrmaAtom(m_SampleEntry->GetType());
// scheme
AP4_SchmAtom* schm = new AP4_SchmAtom(AP4_ISMACRYP_SCHEME_TYPE_IAEC, 1);
// scheme info
AP4_ContainerAtom* schi = new AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI);
AP4_IkmsAtom* ikms = new AP4_IkmsAtom(m_KmsUri.c_str());
AP4_IsfmAtom* isfm = new AP4_IsfmAtom(false, 0, 4);
// populate the schi container
schi->AddChild(ikms);
schi->AddChild(isfm);
// populate the sinf container
sinf->AddChild(frma);
sinf->AddChild(schm);
sinf->AddChild(schi);
// add the sinf atom to the sample description
m_SampleEntry->AddChild(sinf);
// change the atom type of the sample description
m_SampleEntry->SetType(m_Format);
return AP4_SUCCESS;
}
示例2: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| 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;
}
示例3: AP4_DYNAMIC_CAST
/*----------------------------------------------------------------------
| 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;
}
示例4: 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);
}
示例5: AP4_SdpAtom
/*----------------------------------------------------------------------
| AP4_HintTrack::SetSdpText
+---------------------------------------------------------------------*/
void
AP4_HintTrack::SetSdpText(const char* text)
{
// build an sdp atom
AP4_SdpAtom* sdp = DNew AP4_SdpAtom(text);
// build the hnti
AP4_ContainerAtom* hnti = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_HNTI);
hnti->AddChild(sdp);
// check if there's already a user data atom
AP4_ContainerAtom* udta = dynamic_cast<AP4_ContainerAtom*>(m_TrakAtom->FindChild("udta"));
if (udta == NULL) {
// otherwise create it
udta = DNew AP4_ContainerAtom(AP4_ATOM_TYPE_UDTA);
m_TrakAtom->AddChild(udta);
}
udta->AddChild(hnti);
}
示例6: AP4_FrmaAtom
/*----------------------------------------------------------------------
| AP4_OmaDcfTrackEncrypter::ProcessTrack
+---------------------------------------------------------------------*/
AP4_Result
AP4_OmaDcfTrackEncrypter::ProcessTrack()
{
// original format
AP4_FrmaAtom* frma = new AP4_FrmaAtom(m_SampleEntry->GetType());
// scheme info
AP4_OdafAtom* odaf = new AP4_OdafAtom(true, 0, AP4_CIPHER_BLOCK_SIZE);
AP4_OhdrAtom* ohdr = new AP4_OhdrAtom(m_CipherMode,
m_CipherPadding,
0,
m_ContentId.GetChars(),
m_RightsIssuerUrl.GetChars(),
m_TextualHeaders.GetData(),
m_TextualHeaders.GetDataSize());
AP4_SchmAtom* schm = new AP4_SchmAtom(AP4_PROTECTION_SCHEME_TYPE_OMA,
AP4_PROTECTION_SCHEME_VERSION_OMA_20);
// populate the odkm container
AP4_ContainerAtom* odkm = new AP4_ContainerAtom(AP4_ATOM_TYPE_ODKM, (AP4_UI32)0, (AP4_UI32)0);
odkm->AddChild(odaf);
odkm->AddChild(ohdr);
// populate the schi container
AP4_ContainerAtom* schi = new AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI);
schi->AddChild(odkm);
// populate the sinf container
AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF);
sinf->AddChild(frma);
sinf->AddChild(schm);
sinf->AddChild(schi);
// add the sinf atom to the sample description
m_SampleEntry->AddChild(sinf);
// change the atom type of the sample description
m_SampleEntry->SetType(m_Format);
return AP4_SUCCESS;
}
示例7: 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;
//.........这里部分代码省略.........
示例8: if
/*----------------------------------------------------------------------
| AP4_OmaDcfSampleDecrypter::Create
+---------------------------------------------------------------------*/
AP4_Result
AP4_OmaDcfSampleDecrypter::Create(AP4_ProtectedSampleDescription* sample_description,
const AP4_UI08* key,
AP4_Size key_size,
AP4_BlockCipherFactory* block_cipher_factory,
AP4_OmaDcfSampleDecrypter*& cipher)
{
// check the parameters
if (key == NULL || block_cipher_factory == NULL) {
return AP4_ERROR_INVALID_PARAMETERS;
}
// default return value
cipher = NULL;
// default factory
if (block_cipher_factory == NULL) {
block_cipher_factory = &AP4_DefaultBlockCipherFactory::Instance;
}
// get the scheme info atom
AP4_ContainerAtom* schi = sample_description->GetSchemeInfo()->GetSchiAtom();
if (schi == NULL) return AP4_ERROR_INVALID_FORMAT;
// get and check the cipher params
// NOTE: we only support an IV Length less than or equal to the cipher block size,
// and we don't know how to deal with a key indicator length != 0
AP4_OdafAtom* odaf = AP4_DYNAMIC_CAST(AP4_OdafAtom, schi->FindChild("odkm/odaf"));
if (odaf) {
if (odaf->GetIvLength() > AP4_CIPHER_BLOCK_SIZE) return AP4_ERROR_INVALID_FORMAT;
if (odaf->GetKeyIndicatorLength() != 0) return AP4_ERROR_INVALID_FORMAT;
}
// check the scheme details and create the cipher
AP4_OhdrAtom* ohdr = AP4_DYNAMIC_CAST(AP4_OhdrAtom, schi->FindChild("odkm/ohdr"));
if (ohdr == NULL) return AP4_ERROR_INVALID_FORMAT;
AP4_UI08 encryption_method = ohdr->GetEncryptionMethod();
if (encryption_method == AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC) {
// in CBC mode, we only support IVs of the same size as the cipher block size
if (odaf->GetIvLength() != AP4_CIPHER_BLOCK_SIZE) return AP4_ERROR_INVALID_FORMAT;
// require RFC_2630 padding
if (ohdr->GetPaddingScheme() != AP4_OMA_DCF_PADDING_SCHEME_RFC_2630) {
return AP4_ERROR_NOT_SUPPORTED;
}
// create the block cipher
AP4_BlockCipher* block_cipher = NULL;
AP4_Result 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;
// create the cipher
cipher = new AP4_OmaDcfCbcSampleDecrypter(block_cipher,
odaf->GetSelectiveEncryption());
return AP4_SUCCESS;
} else if (encryption_method == AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR) {
// require NONE padding
if (ohdr->GetPaddingScheme() != AP4_OMA_DCF_PADDING_SCHEME_NONE) {
return AP4_ERROR_INVALID_FORMAT;
}
// create the block cipher
AP4_BlockCipher* block_cipher = NULL;
AP4_BlockCipher::CtrParams ctr_params;
ctr_params.counter_size = odaf->GetIvLength();
AP4_Result 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;
// create the cipher
cipher = new AP4_OmaDcfCtrSampleDecrypter(block_cipher,
odaf->GetIvLength(),
odaf->GetSelectiveEncryption());
return AP4_SUCCESS;
} else {
return AP4_ERROR_NOT_SUPPORTED;
}
}
示例9: 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();
//.........这里部分代码省略.........
示例10: AP4_DYNAMIC_CAST
//.........这里部分代码省略.........
// add the iods atom to the moov atom (try to put it just after mvhd)
int iods_position = 0;
int item_position = 0;
for (AP4_List<AP4_Atom>::Item* item = moov->GetChildren().FirstItem();
item;
++item) {
++item_position;
if (item->GetData()->GetType() == AP4_ATOM_TYPE_MVHD) {
iods_position = item_position;
break;
}
}
AP4_Result result = moov->AddChild(iods, iods_position);
if (AP4_FAILED(result)) {
delete iods;
return result;
}
// create a sample table for the OD track
AP4_SyntheticSampleTable* od_sample_table = new AP4_SyntheticSampleTable();
// create the sample description for the OD track
AP4_MpegSystemSampleDescription* od_sample_description;
od_sample_description = new AP4_MpegSystemSampleDescription(AP4_STREAM_TYPE_OD,
AP4_OTI_MPEG4_SYSTEM,
NULL,
32768, // buffer size
1024, // max bitrate
512); // avg bitrate
od_sample_table->AddSampleDescription(od_sample_description, true);
// create the OD descriptor update
AP4_DescriptorUpdateCommand od_update(AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE);
for (unsigned int i=0; i<mpod->GetTrackIds().ItemCount(); i++) {
AP4_ObjectDescriptor* od = new AP4_ObjectDescriptor(AP4_DESCRIPTOR_TAG_MP4_OD, 256+i); // descriptor id = 256+i
od->AddSubDescriptor(new AP4_EsIdRefDescriptor(i+1)); // index into mpod (1-based)
od->AddSubDescriptor(new AP4_IpmpDescriptorPointer(i+1)); // descriptor id = i+1
od_update.AddDescriptor(od);
}
// create the IPMP descriptor update
AP4_DescriptorUpdateCommand ipmp_update(AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE);
for (unsigned int i=0; i<mpod->GetTrackIds().ItemCount(); i++) {
// create the ipmp descriptor
AP4_IpmpDescriptor* ipmp_descriptor = new AP4_IpmpDescriptor(i+1, AP4_MARLIN_IPMPS_TYPE_MGSV);
// create the sinf container
AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF);
// add the scheme type atom
sinf->AddChild(new AP4_SchmAtom(AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACBC, 0x0100, NULL, true));
// setup the scheme info atom
const char* content_id = m_PropertyMap.GetProperty(mpod->GetTrackIds()[i], "ContentId");
if (content_id) {
AP4_ContainerAtom* schi = new AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI);
schi->AddChild(new AP4_NullTerminatedStringAtom(AP4_ATOM_TYPE_8ID_, content_id));
sinf->AddChild(schi);
}
// serialize the sinf atom to a buffer and set it as the ipmp data
AP4_MemoryByteStream* sinf_data = new AP4_MemoryByteStream((AP4_Size)sinf->GetSize());
sinf->Write(*sinf_data);
ipmp_descriptor->SetData(sinf_data->GetData(), sinf_data->GetDataSize());
sinf_data->Release();
ipmp_update.AddDescriptor(ipmp_descriptor);
}
// add the sample with the descriptors and updates
AP4_MemoryByteStream* sample_data = new AP4_MemoryByteStream();
od_update.Write(*sample_data);
ipmp_update.Write(*sample_data);
od_sample_table->AddSample(*sample_data, 0, sample_data->GetDataSize(), 0, 0, 0, 0, true);
// create the OD track
AP4_TrakAtom* od_track = new AP4_TrakAtom(od_sample_table,
AP4_HANDLER_TYPE_ODSM,
"Bento4 Marlin OD Handler",
od_track_id,
0, 0,
1, 1000, 1, 0, "und",
0, 0);
// add an entry in the processor's stream table to indicate that the
// media data for the OD track is not in the file stream, but in our
// memory stream.
m_ExternalTrackData.Add(new ExternalTrackData(od_track_id, sample_data));
sample_data->Release();
// add a tref track reference atom
AP4_ContainerAtom* tref = new AP4_ContainerAtom(AP4_ATOM_TYPE_TREF);
tref->AddChild(mpod);
od_track->AddChild(tref, 1); // add after 'tkhd'
// add the track to the moov atoms (just after the last track)
moov->AddChild(od_track, od_track_position);
return AP4_SUCCESS;
}
示例11: 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
//.........这里部分代码省略.........
示例12: DcfParser_ParseV2Header
/*----------------------------------------------------------------------
| 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;
}
示例13: 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;
}
}
//.........这里部分代码省略.........
示例14: AP4_DYNAMIC_CAST
//.........这里部分代码省略.........
delete iods;
return result;
}
// create a sample table for the OD track
AP4_SyntheticSampleTable* od_sample_table = new AP4_SyntheticSampleTable();
// create the sample description for the OD track
AP4_MpegSystemSampleDescription* od_sample_description;
od_sample_description = new AP4_MpegSystemSampleDescription(AP4_STREAM_TYPE_OD,
AP4_OTI_MPEG4_SYSTEM,
NULL,
32768, // buffer size
1024, // max bitrate
512); // avg bitrate
od_sample_table->AddSampleDescription(od_sample_description, true);
// create the OD descriptor update
AP4_DescriptorUpdateCommand od_update(AP4_COMMAND_TAG_OBJECT_DESCRIPTOR_UPDATE);
for (unsigned int i=0; i<mpod->GetTrackIds().ItemCount(); i++) {
AP4_ObjectDescriptor* od = new AP4_ObjectDescriptor(AP4_DESCRIPTOR_TAG_MP4_OD, 256+i); // descriptor id = 256+i
od->AddSubDescriptor(new AP4_EsIdRefDescriptor(i+1)); // index into mpod (1-based)
od->AddSubDescriptor(new AP4_IpmpDescriptorPointer(i+1)); // descriptor id = i+1
od_update.AddDescriptor(od);
}
// create the IPMP descriptor update
AP4_DescriptorUpdateCommand ipmp_update(AP4_COMMAND_TAG_IPMP_DESCRIPTOR_UPDATE);
for (unsigned int i=0; i<mpod->GetTrackIds().ItemCount(); i++) {
// create the ipmp descriptor
AP4_IpmpDescriptor* ipmp_descriptor = new AP4_IpmpDescriptor(i+1, AP4_MARLIN_IPMPS_TYPE_MGSV);
// create the sinf container
AP4_ContainerAtom* sinf = new AP4_ContainerAtom(AP4_ATOM_TYPE_SINF);
// add the scheme type atom
sinf->AddChild(new AP4_SchmAtom(m_UseGroupKey?
AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACGK:
AP4_PROTECTION_SCHEME_TYPE_MARLIN_ACBC,
0x0100, NULL, true));
// create the 'schi' container
AP4_ContainerAtom* schi = new AP4_ContainerAtom(AP4_ATOM_TYPE_SCHI);
// add the content ID
const char* content_id = m_PropertyMap.GetProperty(mpod->GetTrackIds()[i], "ContentId");
if (content_id) {
// add the content ID (8id_)
schi->AddChild(new AP4_NullTerminatedStringAtom(AP4_ATOM_TYPE_8ID_, content_id));
}
// find what the track type is (necessary for the next step) and the key
const AP4_DataBuffer* key = NULL;
AP4_Track::Type track_type = AP4_Track::TYPE_UNKNOWN;
for (AP4_List<AP4_TrakAtom>::Item* trak_item = moov->GetTrakAtoms().FirstItem();
trak_item;
trak_item = trak_item->GetNext()) {
AP4_TrakAtom* trak = trak_item->GetData();
if (trak->GetId() == mpod->GetTrackIds()[i]) {
// find the handler type
AP4_Atom* sub = trak->FindChild("mdia/hdlr");
if (sub) {
AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, sub);
if (hdlr) {
AP4_UI32 type = hdlr->GetHandlerType();
if (type == AP4_HANDLER_TYPE_SOUN) {
示例15: 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);
}
}
}
}
}
}
}
}
}