/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | AP4_IsmaEncryptingProcessor:CreateTrackHandler +---------------------------------------------------------------------*/ AP4_Processor::TrackHandler* AP4_IsmaEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) { // find the stsd atom AP4_StsdAtom* stsd = dynamic_cast<AP4_StsdAtom*>( trak->FindChild("mdia/minf/stbl/stsd")); // avoid tracks with no stsd atom (should not happen) if (stsd == NULL) return NULL; // only look at the first sample description AP4_SampleEntry* entry = stsd->GetSampleEntry(0); if (entry == NULL) return NULL; // create a handler for this track if we have a key for it and we know // how to map the type const AP4_UI08* key; const AP4_UI08* salt; AP4_UI32 format = 0; if (AP4_SUCCEEDED(m_KeyMap.GetKey(trak->GetId(), key, salt))) { switch (entry->GetType()) { case AP4_ATOM_TYPE_MP4A: format = AP4_ATOM_TYPE_ENCA; break; case AP4_ATOM_TYPE_MP4V: case AP4_ATOM_TYPE_AVC1: format = AP4_ATOM_TYPE_ENCV; break; } if (format) { return new AP4_IsmaTrackEncrypter(m_KmsUri.c_str(), key, salt, entry, format); } } return NULL; }
/*---------------------------------------------------------------------- | AP4_OmaDcfEncryptingProcessor:CreateTrackHandler +---------------------------------------------------------------------*/ AP4_Processor::TrackHandler* AP4_OmaDcfEncryptingProcessor::CreateTrackHandler(AP4_TrakAtom* trak) { // find the stsd atom AP4_StsdAtom* stsd = AP4_DYNAMIC_CAST(AP4_StsdAtom, trak->FindChild("mdia/minf/stbl/stsd")); // avoid tracks with no stsd atom (should not happen) if (stsd == NULL) return NULL; // only look at the first sample description AP4_SampleEntry* entry = stsd->GetSampleEntry(0); if (entry == NULL) return NULL; // create a handler for this track if we have a key for it and we know // how to map the type const AP4_DataBuffer* key; const AP4_DataBuffer* iv; AP4_UI32 format = 0; if (AP4_SUCCEEDED(m_KeyMap.GetKeyAndIv(trak->GetId(), key, iv))) { switch (entry->GetType()) { case AP4_ATOM_TYPE_MP4A: format = AP4_ATOM_TYPE_ENCA; break; case AP4_ATOM_TYPE_MP4V: case AP4_ATOM_TYPE_AVC1: case AP4_ATOM_TYPE_AVC2: case AP4_ATOM_TYPE_AVC3: case AP4_ATOM_TYPE_AVC4: case AP4_ATOM_TYPE_HEV1: case AP4_ATOM_TYPE_HVC1: format = AP4_ATOM_TYPE_ENCV; break; default: { // try to find if this is audio or video AP4_HdlrAtom* hdlr = AP4_DYNAMIC_CAST(AP4_HdlrAtom, trak->FindChild("mdia/hdlr")); if (hdlr) { switch (hdlr->GetHandlerType()) { case AP4_HANDLER_TYPE_SOUN: format = AP4_ATOM_TYPE_ENCA; break; case AP4_HANDLER_TYPE_VIDE: format = AP4_ATOM_TYPE_ENCV; break; } } break; } } if (format) { const char* content_id = m_PropertyMap.GetProperty(trak->GetId(), "ContentId"); const char* rights_issuer_url = m_PropertyMap.GetProperty(trak->GetId(), "RightsIssuerUrl"); AP4_DataBuffer textual_headers; AP4_Result result = m_PropertyMap.GetTextualHeaders(trak->GetId(), textual_headers); if (AP4_FAILED(result)) textual_headers.SetDataSize(0); // create the block cipher AP4_BlockCipher* block_cipher = NULL; AP4_BlockCipher::CtrParams ctr_params; AP4_BlockCipher::CipherMode cipher_mode; const void* cipher_params = NULL; if (m_CipherMode == AP4_OMA_DCF_CIPHER_MODE_CBC) { cipher_mode = AP4_BlockCipher::CBC; } else if (m_CipherMode == AP4_OMA_DCF_CIPHER_MODE_CTR) { cipher_mode = AP4_BlockCipher::CTR; ctr_params.counter_size = 16; cipher_params = &ctr_params; } else { return NULL; } result = m_BlockCipherFactory->CreateCipher(AP4_BlockCipher::AES_128, AP4_BlockCipher::ENCRYPT, cipher_mode, cipher_params, key->GetData(), key->GetDataSize(), block_cipher); if (AP4_FAILED(result)) return NULL; return new AP4_OmaDcfTrackEncrypter(m_CipherMode, block_cipher, iv->GetData(), entry, format, content_id, rights_issuer_url, textual_headers.GetData(), textual_headers.GetDataSize()); } } return NULL; }