⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4drm.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  std::string contentURLHdr;  std::string contentVerHdr;  std::string contentLocHdr;  UInt64T pTextLen;};/*! \brief  Encrypts MP4 data using AES128CTR encryptor according to openIPMP            specifications with Sinf signalling.    Encrypts samples and adds information for decryption to MP4 stream.*/class AES128CTROpenIPMPMPEG4SinfDRMEncryptor: public IMPEG4SinfDRMEncryptor {public:  /*! \brief  Constructor.      Mandatory tags in the XML file are:       - ROOT.RightsHostInfo      Here follows an example of a correctly formatted XML document.      \verbatim      <ROOT>       <RightsHostInfo>localhost:8080</RightsHostInfo>      </ROOT>      \endverbatim      \param      drm             input, DRM manager.      \param      conID           input, content identifier.      \param      xmlDoc          input, XML document.      \param      logger          input-output, message logger.      If constructor fails, it throws MPEG4DRMPluginException.  */  AES128CTROpenIPMPMPEG4SinfDRMEncryptor(IDRMEncManager* drm, std::string& conID,      DRMPlugin::IXMLElement* xmlDoc, DRMLogger& logger): encryptor(0), contentID(),      rightsHost() {    if (xmlDoc == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::ctor: zero XML file.");      throw MPEG4DRMPluginException();    }    encryptor = drm->CreateAES128CTREnc(conID, xmlDoc, logger);    if (encryptor == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::ctor: zero encryptor.");      throw MPEG4DRMPluginException();    }    contentID = conID;    try {      rightsHost = xmlDoc->GetChildStrValue("RightsHostInfo");    }    catch (XMLException) {      delete encryptor;      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::ctor: missing data in XML file.");      throw MPEG4DRMPluginException();    }  }  virtual ~AES128CTROpenIPMPMPEG4SinfDRMEncryptor() {    if (encryptor != 0) delete encryptor;  }  /*! \brief  Encrypt sample sampleBuffer.        Returns encrypted sample in encSampleData.      \param    sampleBuffer      input, sample to be encrypted.      \param    sampleSize        input, size of input sample.      \param    encSampleData     output, encrypted sample.      \param    encSampleLen      output, size of encrypted sample.      \param    logger            input-output, message logger.      \return Boolean indicating success or failure. In case of failure,              logger's log will contain error message.  */  virtual bool EncryptSample(ByteT* sampleBuffer, UInt32T sampleSize,      ByteT** encSampleData, UInt32T* encSampleLen, DRMLogger& logger) {    //  Get next counter.    ByteT* ctr;    UInt32T ctrLen;    if (encryptor->NextCtr(&ctr, &ctrLen, logger) == false) {      return false;    }    //  Encrypt sample.    ByteT* enc;    UInt32T encLen;    //  Encrypt sample.    if (encryptor->Encrypt(sampleBuffer, sampleSize, &enc, &encLen, logger) == false) {      if (ctr != NULL) {        free(ctr);      }      return false;    }    /*  Allocate memory (1 for counter length + size of the counter + size of the        encrypted block).    */    *encSampleData = (ByteT*)malloc(1 + ctrLen + encLen);    if (*encSampleData == NULL) {      if (ctr != NULL) {        free(ctr);      }      if (enc != NULL) {        free(enc);      }      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::EncryptSample: memory allocation error.");      return false;    }    *encSampleLen = 1 + ctrLen + encLen;    ByteT* tmp = *encSampleData;    //  Add header.    //  Counter length.    *tmp++ = (ByteT)ctrLen;    memcpy(tmp, ctr, ctrLen);    tmp += ctrLen;    memcpy(tmp, enc, encLen);    if (ctr != NULL) {      free(ctr);    }    if (enc != NULL) {      free(enc);    }    return true;  }  /*! \brief  Add drm information into sinf atom.        Caller must take care that given sinf atom really coresponds to sample      description atom which refers to encrypted samples.      \param    originalFormat  input, 4CC code of the original data format.      \param    sinf            input-output, sinf atom where to add drm information.      \param    logger          input-output, message logger.      \return Boolean indicating success or failure. In case of failure,              logger's log will contain error message.  */  virtual bool Finish(UInt32T originalFormat, MP4Atom* sinf, DRMLogger& logger) {	  MP4Atom* frma = sinf->FindChildAtom("frma");    if (frma == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: no original format atom.");      return false;    }	  MP4Property* data_format = 0;	  frma->FindProperty("frma.data-format", &data_format, 0); 		  if (data_format == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: frma->SetDataFormat() error.");      return false;	  }    ((MP4Integer32Property*)data_format)->SetValue(originalFormat);    MP4Atom* imif = sinf->CreateAtom("imif");    if (imif == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: could not create IPMP info atom.");      return false;    }    sinf->AddChildAtom(imif);    imif->Generate();	  MP4Property* ipmp_desc = 0;	  imif->FindProperty("imif.ipmp_desc", &ipmp_desc, 0); 		  if (ipmp_desc == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: missing IPMP descriptor property.");      return false;	  }    MP4Descriptor* ipmpDesc = ((MP4DescriptorProperty*)ipmp_desc)->AddDescriptor(MP4IPMPDescrTag);    if (ipmpDesc == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: could not create IPMP descriptor.");      return false;    }	  MP4Property* IPMPDescriptorId = 0;	  ipmpDesc->FindProperty("IPMPDescriptorId", &IPMPDescriptorId, 0); 		  if (IPMPDescriptorId == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: ipmpDesc->SetIPMPDescriptorIdentifier() error.");      return false;	  }    ((MP4Integer8Property*)IPMPDescriptorId)->SetValue(255);	  MP4Property* IPMPSType = 0;	  ipmpDesc->FindProperty("IPMPSType", &IPMPSType, 0); 		  if (IPMPSType == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: ipmpDesc->SetIPMPDescriptorType() error.");      return false;	  }    ((MP4Integer16Property*)IPMPSType)->SetValue(65535);    std::string toolID = OPENIPMP_TOOLID;    UInt32T ipmpDataSize = 1 + toolID.size() + 1 + contentID.size() + 1 + rightsHost.size() + 1;    ByteT* ipmpData = (ByteT*)malloc(ipmpDataSize);    if (ipmpData == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: memory allocation error.");      return false;    }    //  Save the encryption method.    *ipmpData = (ByteT)(AES128CTR);    memcpy(ipmpData + 1, toolID.data(), toolID.size() + 1);    memcpy(ipmpData + 1 + toolID.size() + 1, contentID.data(), contentID.size() + 1);    memcpy(ipmpData + 1 + toolID.size() + 1 + contentID.size() + 1, rightsHost.data(),      rightsHost.size() + 1);	  MP4Property* IPMPData = 0;	  ipmpDesc->FindProperty("IPMPData", &IPMPData, 0); 		  if (IPMPData == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: ipmpDesc->SetIPMPData() error.");      return false;	  }    ((MP4BytesProperty*)IPMPData)->SetValue((u_int8_t*)ipmpData, ipmpDataSize);    free(ipmpData);    return true;  }private:  AES128CTREncryptor* encryptor;  std::string contentID;  std::string rightsHost;};/*! \brief  Encrypts MP4 data using blowfish encryptor according to openIPMP            specifications with Sinf signalling.    Encrypts samples and adds information for decryption to MP4 stream.*/class BlowfishOpenIPMPMPEG4SinfDRMEncryptor: public IMPEG4SinfDRMEncryptor {public:  /*! \brief  Constructor.      Mandatory tags in the XML file are:       - ROOT.RightsHostInfo      Here follows an example of a correctly formatted XML document.      \verbatim      <ROOT>       <RightsHostInfo>localhost:8080</RightsHostInfo>      </ROOT>      \endverbatim      \param      drm             input, DRM manager.      \param      conID           input, content identifier.      \param      xmlDoc          input, XML document.      \param      logger          input-output, message logger.      If constructor fails, it throws MPEG4DRMPluginException.  */  BlowfishOpenIPMPMPEG4SinfDRMEncryptor(IDRMEncManager* drm, std::string& conID,      DRMPlugin::IXMLElement* xmlDoc, DRMLogger& logger): encryptor(), contentID(),      rightsHost() {    if (xmlDoc == 0) {      logger.UpdateLog("BlowfishOpenIPMPMPEG4SinfDRMEncryptor::ctor: zero XML file.");      throw MPEG4DRMPluginException();    }    encryptor = drm->CreateBlowfishEnc(conID, xmlDoc, logger);    if (encryptor == 0) {      logger.UpdateLog("BlowfishOpenIPMPMPEG4SinfDRMEncryptor::ctor: zero encryptor.");      throw MPEG4DRMPluginException();    }    contentID = conID;    try {      rightsHost = xmlDoc->GetChildStrValue("RightsHostInfo");    }    catch (XMLException) {      delete encryptor;      logger.UpdateLog("BlowfishOpenIPMPMPEG4SinfDRMEncryptor::ctor: missing data in XML file.");      throw MPEG4DRMPluginException();    }  }  virtual ~BlowfishOpenIPMPMPEG4SinfDRMEncryptor() {    if (encryptor != 0) delete encryptor;  }  /*! \brief  Encrypt sample sampleBuffer.        Returns encrypted sample in encSampleData.      \param    sampleBuffer      input, sample to be encrypted.      \param    sampleSize        input, size of input sample.      \param    encSampleData     output, encrypted sample.      \param    encSampleLen      output, size of encrypted sample.      \param    logger            input-output, message logger.      \return Boolean indicating success or failure. In case of failure,              logger's log will contain error message.  */  virtual bool EncryptSample(ByteT* sampleBuffer, UInt32T sampleSize,      ByteT** encSampleData, UInt32T* encSampleLen, DRMLogger& logger) {    return encryptor->Encrypt(sampleBuffer, sampleSize, encSampleData, encSampleLen,      logger);  }  /*! \brief  Add drm information into sinf atom.        Caller must take care that given sinf atom really coresponds to sample      description atom which refers to encrypted samples.      \param    originalFormat  input, 4CC code of the original data format.      \param    sinf            input-output, sinf atom where to add drm information.      \param    logger          input-output, message logger.      \return Boolean indicating success or failure. In case of failure,              logger's log will contain error message.  */  virtual bool Finish(UInt32T originalFormat, MP4Atom* sinf, DRMLogger& logger) {	  MP4Atom* frma = sinf->FindChildAtom("frma");    if (frma == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: no original format atom.");      return false;    }	  MP4Property* data_format = 0;	  frma->FindProperty("frma.data-format", &data_format, 0); 		  if (data_format == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: frma->SetDataFormat() error.");      return false;	  }    ((MP4Integer32Property*)data_format)->SetValue(originalFormat);    MP4Atom* imif = sinf->CreateAtom("imif");    if (imif == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: could not create IPMP info atom.");      return false;    }    sinf->AddChildAtom(imif);    imif->Generate();	  MP4Property* ipmp_desc = 0;	  imif->FindProperty("imif.ipmp_desc", &ipmp_desc, 0); 		  if (ipmp_desc == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: missing IPMP descriptor property.");      return false;	  }    MP4Descriptor* ipmpDesc = ((MP4DescriptorProperty*)ipmp_desc)->AddDescriptor(MP4IPMPDescrTag);    if (ipmpDesc == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: could not create IPMP descriptor.");      return false;    }	  MP4Property* IPMPDescriptorId = 0;	  ipmpDesc->FindProperty("IPMPDescriptorId", &IPMPDescriptorId, 0); 		  if (IPMPDescriptorId == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: ipmpDesc->SetIPMPDescriptorIdentifier() error.");      return false;	  }    ((MP4Integer8Property*)IPMPDescriptorId)->SetValue(255);	  MP4Property* IPMPSType = 0;	  ipmpDesc->FindProperty("IPMPSType", &IPMPSType, 0); 		  if (IPMPSType == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: ipmpDesc->SetIPMPDescriptorType() error.");      return false;	  }    ((MP4Integer16Property*)IPMPSType)->SetValue(65535);    std::string toolID = OPENIPMP_TOOLID;    UInt32T ipmpDataSize = 1 + toolID.size() + 1 + contentID.size() + 1 + rightsHost.size() + 1;    ByteT* ipmpData = (ByteT*)malloc(ipmpDataSize);    if (ipmpData == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: memory allocation error.");      return false;    }    //  Save the encryption method.    *ipmpData = (ByteT)(BLOWFISH);    memcpy(ipmpData + 1, toolID.data(), toolID.size() + 1);    memcpy(ipmpData + 1 + toolID.size() + 1, contentID.data(), contentID.size() + 1);    memcpy(ipmpData + 1 + toolID.size() + 1 + contentID.size() + 1, rightsHost.data(),      rightsHost.size() + 1);	  MP4Property* IPMPData = 0;	  ipmpDesc->FindProperty("IPMPData", &IPMPData, 0); 		  if (IPMPData == 0) {      logger.UpdateLog("AES128CTROpenIPMPMPEG4SinfDRMEncryptor::Finish: ipmpDesc->SetIPMPData() error.");      return false;	  }    ((MP4BytesProperty*)IPMPData)->SetValue((u_int8_t*)ipmpData, ipmpDataSize);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -