/*---------------------------------------------------------------------- | AP4_IsmaDecryptingProcessor:CreateTrackHandler +---------------------------------------------------------------------*/ AP4_Processor::TrackHandler* AP4_IsmaDecryptingProcessor::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; // we only look at the first sample description AP4_SampleDescription* desc = stsd->GetSampleDescription(0); AP4_SampleEntry* entry = stsd->GetSampleEntry(0); if (desc == NULL || entry == NULL) return NULL; if (desc->GetType() == AP4_SampleDescription::TYPE_ISMACRYP) { // create a handler for this track AP4_IsmaCrypSampleDescription* ismacryp_desc = static_cast<AP4_IsmaCrypSampleDescription*>(desc); if (ismacryp_desc->GetSchemeType() == AP4_ISMACRYP_SCHEME_TYPE_IAEC) { const AP4_UI08* key; const AP4_UI08* salt; if (AP4_SUCCEEDED(m_KeyMap.GetKey(trak->GetId(), key, salt))) { return new AP4_IsmaTrackDecrypter(key, salt, ismacryp_desc, entry); } } } return NULL; }
virtual TrackHandler* 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; // we only look at the first sample description AP4_SampleDescription* desc = stsd->GetSampleDescription(0); AP4_MpegAudioSampleDescription* audio_desc = AP4_DYNAMIC_CAST(AP4_MpegAudioSampleDescription, desc); if (audio_desc && audio_desc->GetObjectTypeId()==AP4_OTI_MPEG2_AAC_AUDIO_LC) { // patch the stsd AP4_MpegAudioSampleDescription new_audio_desc(AP4_OTI_MPEG4_AUDIO, audio_desc->GetSampleRate(), audio_desc->GetSampleSize(), audio_desc->GetChannelCount(), &audio_desc->GetDecoderInfo(), audio_desc->GetBufferSize(), audio_desc->GetMaxBitrate(), audio_desc->GetAvgBitrate()); stsd->RemoveChild(stsd->GetChild(AP4_ATOM_TYPE_MP4A)); stsd->AddChild(new_audio_desc.ToAtom()); printf("audio sample description patched\n"); } return NULL; }
/*---------------------------------------------------------------------- | 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; }