/*---------------------------------------------------------------------- | DcfParser_Construct +---------------------------------------------------------------------*/ static void DcfParser_Construct(DcfParser* self, BLT_Module* module, BLT_Core* core) { /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* construct the members */ DcfParserInput_Construct(&self->input, module); DcfParserOutput_Construct(&self->output); /* look for a key manager */ ATX_Properties* properties = NULL; if (BLT_SUCCEEDED(BLT_Core_GetProperties(core, &properties))) { ATX_PropertyValue value; if (ATX_SUCCEEDED(ATX_Properties_GetProperty(properties, BLT_KEY_MANAGER_PROPERTY, &value))) { if (value.type == ATX_PROPERTY_VALUE_TYPE_POINTER) { self->key_manager = (BLT_KeyManager*)value.data.pointer; } } else { ATX_LOG_FINE("no key manager"); } /* check if we need to use a cipher factory */ if (ATX_SUCCEEDED(ATX_Properties_GetProperty(properties, BLT_CIPHER_FACTORY_PROPERTY, &value))) { if (value.type == ATX_PROPERTY_VALUE_TYPE_POINTER) { self->cipher_factory = new BLT_Ap4CipherFactoryAdapter((BLT_CipherFactory*)value.data.pointer); } } else { ATX_LOG_FINE("no cipher factory"); } } /* setup interfaces */ ATX_SET_INTERFACE_EX(self, DcfParser, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, DcfParser, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(&self->input, DcfParserInput, BLT_MediaPort); ATX_SET_INTERFACE(&self->input, DcfParserInput, BLT_InputStreamUser); ATX_SET_INTERFACE(&self->output, DcfParserOutput, BLT_MediaPort); ATX_SET_INTERFACE(&self->output, DcfParserOutput, BLT_InputStreamProvider); }
/*---------------------------------------------------------------------- | Mp4ParserOutput_ProcessCryptoInfo +---------------------------------------------------------------------*/ static BLT_Result Mp4ParserOutput_ProcessCryptoInfo(Mp4ParserOutput* self, AP4_SampleDescription*& sample_desc) { // check if the track is encrypted if (sample_desc->GetType() == AP4_SampleDescription::TYPE_PROTECTED) { ATX_LOG_FINE("track is encrypted"); AP4_ProtectedSampleDescription* prot_desc = dynamic_cast<AP4_ProtectedSampleDescription*>(sample_desc); if (prot_desc == NULL) { ATX_LOG_FINE("unable to obtain cipher info"); return BLT_ERROR_INVALID_MEDIA_FORMAT; } // obtain the key manager if (self->parser->key_manager == NULL) { ATX_Properties* properties = NULL; if (BLT_SUCCEEDED(BLT_Core_GetProperties(ATX_BASE(self->parser, BLT_BaseMediaNode).core, &properties))) { ATX_PropertyValue value; if (ATX_SUCCEEDED(ATX_Properties_GetProperty(properties, BLT_KEY_MANAGER_PROPERTY, &value))) { if (value.type == ATX_PROPERTY_VALUE_TYPE_POINTER) { self->parser->key_manager = (BLT_KeyManager*)value.data.pointer; } } else { ATX_LOG_FINE("no key manager"); } } } if (self->parser->key_manager == NULL) return BLT_ERROR_NO_MEDIA_KEY; // check if we need to use a cipher factory if (self->parser->cipher_factory == NULL) { ATX_Properties* properties = NULL; if (BLT_SUCCEEDED(BLT_Core_GetProperties(ATX_BASE(self->parser, BLT_BaseMediaNode).core, &properties))) { ATX_PropertyValue value; if (ATX_SUCCEEDED(ATX_Properties_GetProperty(properties, BLT_CIPHER_FACTORY_PROPERTY, &value))) { if (value.type == ATX_PROPERTY_VALUE_TYPE_POINTER) { self->parser->cipher_factory = new BLT_Ap4CipherFactoryAdapter((BLT_CipherFactory*)value.data.pointer); } } } } // figure out the content ID for this track // TODO: support different content ID schemes // for now, we just make up a content ID based on the track ID char content_id[32]; NPT_FormatString(content_id, sizeof(content_id), "@track.%d", self->track->GetId()); // get the key for this content unsigned int key_size = 256; NPT_DataBuffer key(key_size); BLT_Result result = BLT_KeyManager_GetKeyByName(self->parser->key_manager, content_id, key.UseData(), &key_size); if (result == ATX_ERROR_NOT_ENOUGH_SPACE) { key.SetDataSize(key_size); result = BLT_KeyManager_GetKeyByName(self->parser->key_manager, content_id, key.UseData(), &key_size); } if (BLT_FAILED(result)) return BLT_ERROR_NO_MEDIA_KEY; key.SetDataSize(key_size); delete self->sample_decrypter; self->sample_decrypter = AP4_SampleDecrypter::Create(prot_desc, key.GetData(), key_size, self->parser->cipher_factory); if (self->sample_decrypter == NULL) { ATX_LOG_FINE("unable to create decrypter"); return BLT_ERROR_CRYPTO_FAILURE; } // switch to the original sample description sample_desc = prot_desc->GetOriginalSampleDescription(); } return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | BLT_Decoder_GetProperties +---------------------------------------------------------------------*/ BLT_Result BLT_Decoder_GetProperties(BLT_Decoder* decoder, ATX_Properties** properties) { return BLT_Core_GetProperties(decoder->core, properties); }