📄 mp4_drm_bytestream.cpp
字号:
iSFM->FindProperty("iSFM.key-indicator-length", &key_indicator_length, 0); if (key_indicator_length == 0) { // Error. Check the ctor. return false; } MP4Property* IV_length = 0; iSFM->FindProperty("iSFM.IV-length", &IV_length, 0); if (IV_length == 0) { // Error. Check the ctor. return false; } u_int8_t* IPMP; u_int32_t tSize; ((MP4BytesProperty*)IPMPData)->GetValue(&IPMP, &tSize); try { ISMADRMInfo info((ByteT*)IPMP, ((MP4BytesProperty*)IPMPData)->GetValueSize(0), ((MP4Integer32Property*)scheme_version)->GetValue(), ((MP4StringProperty*)kms_URI)->GetValue(), (((MP4BitfieldProperty*)selective_encryption)->GetValue() != 0), ((MP4Integer8Property*)key_indicator_length)->GetValue(), ((MP4Integer8Property*)IV_length)->GetValue(), logger); MP4Free(IPMP); if (id2Dec.find(info.GetContentID()) != id2Dec.end()) { *decryptor = id2Dec[info.GetContentID()]; return true; } IISMADRMDecManager* manager = ISMADRMDecManagerFactory::GetISMADRMDecManager(GetXML(), logger); if (manager == 0) { return false; } *decryptor = manager->CreateDecryptor(info, GetXML(), logger); delete manager; if (*decryptor != 0) { id2Dec[info.GetContentID()] = *decryptor; } return (*decryptor != 0); } catch (DRMInfoException) { MP4Free(IPMP); return false; } } else { // Unknown protection scheme. return false; } } else if (imif != 0) { MP4Property* ipmp_desc = 0; imif->FindProperty("imif.ipmp_desc", &ipmp_desc, 0); if (ipmp_desc == 0) { // Error. Check the ctor. return false; } if (((MP4DescriptorProperty*)ipmp_desc)->GetCount() == 0) { // No IPMP descriptors. return false; } MP4Property* IPMPDescriptorId = 0; ((MP4DescriptorProperty*)ipmp_desc)->FindProperty("ipmp_desc.IPMPDescriptorId", &IPMPDescriptorId, 0); if (IPMPDescriptorId == 0) { // Error. Check the ctor. return false; } MP4Property* IPMPSType = 0; ((MP4DescriptorProperty*)ipmp_desc)->FindProperty("ipmp_desc.IPMPSType", &IPMPSType, 0); if (IPMPSType == 0) { // Error. Check the ctor. return false; } if (((MP4Integer8Property*)IPMPDescriptorId)->GetValue() != 255) { // Error. return false; } if (((MP4Integer16Property*)IPMPSType)->GetValue() != 65535) { // Error. return false; } MP4Property* IPMPData = 0; ((MP4DescriptorProperty*)ipmp_desc)->FindProperty("ipmp_desc.IPMPData", &IPMPData, 0); if (IPMPData == 0) { // Error. Check the ctor. return false; } u_int8_t* IPMP; u_int32_t tSize; ((MP4BytesProperty*)IPMPData)->GetValue(&IPMP, &tSize); // We recognized "openIPMP" protection. try { OpenIPMPDRMInfo info((ByteT*)IPMP, ((MP4BytesProperty*)IPMPData)->GetValueSize(0), logger); MP4Free(IPMP); if (id2Dec.find(info.GetContentID()) != id2Dec.end()) { *decryptor = id2Dec[info.GetContentID()]; return true; } IOpenIPMPDRMDecManager* manager = OpenIPMPDRMDecManagerFactory::GetOpenIPMPDRMDecManager(GetXML(), logger); if (manager == 0) { return false; } *decryptor = manager->CreateDecryptor(info, GetXML(), logger); delete manager; if (*decryptor != 0) { id2Dec[info.GetContentID()] = *decryptor; } return (*decryptor != 0); } catch (DRMInfoException) { MP4Free(IPMP); return false; } } else { // No protection defined. return true; } }private: SDL_mutex *drm_mutex; DRMPlugin::IXMLDocument* doc; DRMPlugin::IXMLElement* xmlDoc; std::map<std::string, IDRMDecryptor*> id2Dec;};/*! \brief Global decryptor holder. Takes care of all DRM related stuff.*/static DecryptorHolder holder;/*! \brief Get contained sinf atom if exists. \param m_track input, track identifier. \param m_parent input, mp4 file. \param pts input, timestamp. \returns Sinf atom.*/static MP4Atom* GetSinfAtom(MP4TrackId m_track, CMp4File *m_parent, frame_timestamp_t *pts) { MP4Track* track = ((MP4File*)(m_parent->get_file()))->GetTrack(m_track); MP4Atom* m_pTrakAtom = track->GetTrakAtom(); MP4Integer32Property* m_pStscCountProperty; MP4Integer32Property* m_pStscSampleDescrIndexProperty; MP4Integer32Property* m_pStscFirstSampleProperty; if (m_pTrakAtom->FindProperty("trak.mdia.minf.stbl.stsc.entryCount", (MP4Property**)&m_pStscCountProperty) == false) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } if (m_pTrakAtom->FindProperty("trak.mdia.minf.stbl.stsc.entries.sampleDescriptionIndex", (MP4Property**)&m_pStscSampleDescrIndexProperty) == false) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } if (m_pTrakAtom->FindProperty("trak.mdia.minf.stbl.stsc.entries.firstSample", (MP4Property**)&m_pStscFirstSampleProperty) == false) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } MP4SampleId sampleId = track->GetSampleIdFromTime(pts->msec_timestamp); u_int32_t stscIndex; u_int32_t numStscs = m_pStscCountProperty->GetValue(); if (numStscs == 0) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } for (stscIndex = 0; stscIndex < numStscs; stscIndex++) { if (sampleId < m_pStscFirstSampleProperty->GetValue(stscIndex)) { if (stscIndex == 0) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } stscIndex -= 1; break; } } if (stscIndex == numStscs) { if (stscIndex == 0) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } stscIndex -= 1; } u_int32_t stsdIndex = m_pStscSampleDescrIndexProperty->GetValue(stscIndex); MP4Atom* pStsdAtom = m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd"); if (pStsdAtom == 0) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } MP4Atom* pStsdEntryAtom = pStsdAtom->GetChildAtom(stsdIndex - 1); if (pStsdEntryAtom == 0) { /* This is an error, but we don't handle it here, cause it should be handled while parsing mp4 atoms. */ return 0; } return pStsdEntryAtom->FindChildAtom("sinf");}/*! Access protected video stream.*//*! \brief Constructor.*/CMp4DRMVideoByteStream::CMp4DRMVideoByteStream(CMp4File *parent, MP4TrackId track): CMp4VideoByteStream(parent, track), dBuffer(0), dBuflen(0) {}/*! \brief Destructor.*/CMp4DRMVideoByteStream::~CMp4DRMVideoByteStream() { if (dBuffer != 0) { free(dBuffer); dBuffer = 0; } dBuflen = 0;} bool CMp4DRMVideoByteStream::start_next_frame (uint8_t **buffer, uint32_t *buflen, frame_timestamp_t *pts, void **ud) { if (CMp4VideoByteStream::start_next_frame(buffer, buflen, pts, ud) == false) { return false; } if (*buffer != NULL) { // Get DRM info. MP4Atom* sinf = GetSinfAtom(m_track, m_parent, pts); // Decrypt sample. if (sinf != 0) { try { IDRMDecryptor* decryptor = 0; if (holder.GetDecryptor(sinf, &decryptor, DRMLogger()) == false) { *buffer = NULL; *buflen = 0; return false; } if (decryptor != 0) { if (dBuffer != 0) { free(dBuffer); dBuffer = 0; } dBuflen = 0; if (decryptor->Decrypt((ByteT*)*buffer, *buflen, (ByteT**)&dBuffer, &dBuflen, DRMLogger()) == false) { *buffer = NULL; *buflen = 0; return false; } *buffer = dBuffer; *buflen = dBuflen; } } catch (...) { *buffer = NULL; *buflen = 0; return false; } } } return true;}/*! Access protected audio stream.*//*! \brief Constructor.*/CMp4DRMAudioByteStream::CMp4DRMAudioByteStream(CMp4File *parent, MP4TrackId track): CMp4AudioByteStream(parent, track), dBuffer(0), dBuflen(0) {}/*! \brief Destructor.*/CMp4DRMAudioByteStream::~CMp4DRMAudioByteStream() { if (dBuffer != 0) { free(dBuffer); dBuffer = 0; } dBuflen = 0;}bool CMp4DRMAudioByteStream::start_next_frame (uint8_t **buffer, uint32_t *buflen, frame_timestamp_t *pts, void **ud) { if (CMp4AudioByteStream::start_next_frame(buffer, buflen, pts, ud) == false) { return false; } if (*buffer != NULL) { // Get DRM info. MP4Atom* sinf = GetSinfAtom(m_track, m_parent, pts); // Decrypt sample. if (sinf != 0) { try { IDRMDecryptor* decryptor = 0; if (holder.GetDecryptor(sinf, &decryptor, DRMLogger()) == false) { *buffer = NULL; *buflen = 0; return false; } if (decryptor != 0) { if (dBuffer != 0) { free(dBuffer); dBuffer = 0; } dBuflen = 0; if (decryptor->Decrypt((ByteT*)*buffer, *buflen, (ByteT**)&dBuffer, &dBuflen, DRMLogger()) == false) { *buffer = NULL; *buflen = 0; return false; } *buffer = dBuffer; *buflen = dBuflen; } } catch (...) { *buffer = NULL; *buflen = 0; return false; } } } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -