diff --git a/framework/base/media/AVAFPacket.h b/framework/base/media/AVAFPacket.h index 175c70412..333ac6cc0 100644 --- a/framework/base/media/AVAFPacket.h +++ b/framework/base/media/AVAFPacket.h @@ -6,6 +6,7 @@ #define FRAMEWORK_AVPACKET_H #include "base/media/IAFPacket.h" +#include extern "C" { #include @@ -47,9 +48,22 @@ class AVAFPacket : public IAFPacket { explicit operator AVPacket *(); + void setMagicKey(const std::string &key) override + { + if (mMagicKey.empty()) { + mMagicKey = key; + } + } + + std::string getMagicKey() override + { + return mMagicKey; + } + private: AVPacket *mpkt{nullptr}; bool mIsProtected; + std::string mMagicKey{}; void copyInfo(); }; @@ -100,13 +114,12 @@ static inline AVFrame *getAVFrame(IAFFrame *frame) static inline AVPacket *getAVPacket(IAFPacket *packet) { - auto * avafPacket = dynamic_cast(packet); + auto *avafPacket = dynamic_cast(packet); if (avafPacket) { return static_cast(*(avafPacket)); } return nullptr; - } -#endif //FRAMEWORK_AVPACKET_H +#endif//FRAMEWORK_AVPACKET_H diff --git a/framework/base/media/IAFPacket.h b/framework/base/media/IAFPacket.h index 4b020a00c..3b3f1cfe9 100644 --- a/framework/base/media/IAFPacket.h +++ b/framework/base/media/IAFPacket.h @@ -12,7 +12,7 @@ #include #include #include - +#include extern "C" { //#include }; @@ -93,6 +93,16 @@ class CICADA_CPLUS_EXTERN IAFPacket { } } + virtual std::string getMagicKey() + { + return ""; + } + + virtual void setMagicKey(const std::string & key) + { + + } + protected: packetInfo mInfo{}; diff --git a/framework/demuxer/avFormatDemuxer.cpp b/framework/demuxer/avFormatDemuxer.cpp index dd3a33545..b615fb397 100644 --- a/framework/demuxer/avFormatDemuxer.cpp +++ b/framework/demuxer/avFormatDemuxer.cpp @@ -354,6 +354,10 @@ namespace Cicada { packet = unique_ptr(new AVAFPacket(&pkt, mSecretDemxuer)); + if (mSecretDemxuer){ + packet->setMagicKey(mDrmMagicKey); + } + if (needUpdateExtraData) { packet->setExtraData(new_extradata, new_extradata_size); } diff --git a/framework/demuxer/avFormatDemuxer.h b/framework/demuxer/avFormatDemuxer.h index 0c0c4c903..5a15a93ed 100644 --- a/framework/demuxer/avFormatDemuxer.h +++ b/framework/demuxer/avFormatDemuxer.h @@ -126,6 +126,7 @@ namespace Cicada { AVFormatContext *mCtx = nullptr; int MAX_QUEUE_SIZE = 60; // about 500ms video and audio packet bool mSecretDemxuer{false}; + std::string mDrmMagicKey{}; private: std::atomic_bool mInterrupted{false}; diff --git a/framework/demuxer/play_list/HLSStream.cpp b/framework/demuxer/play_list/HLSStream.cpp index 0d604246d..34f4c062c 100644 --- a/framework/demuxer/play_list/HLSStream.cpp +++ b/framework/demuxer/play_list/HLSStream.cpp @@ -640,6 +640,10 @@ namespace Cicada { } mSegDecrypter->flush(); + + if (mDRMMagicKey.empty() && mSegKeySource){ + mDRMMagicKey = mSegKeySource->GetOption("drmMagicKey"); + } } else if (mCurSeg->encryption.method == SegmentEncryption::AES_PRIVATE) { memset(mKey, 0, 16); long length = mCurSeg->encryption.keyUrl.length(); @@ -661,6 +665,9 @@ namespace Cicada { mSegDecrypter->SetOption("decryption key", mKey, 16); mSegDecrypter->SetOption("decryption IV", &mCurSeg->encryption.iv[0], 16); mSegDecrypter->flush(); + if (mDRMMagicKey.empty() && mSegKeySource){ + mDRMMagicKey = mSegDecrypter->GetOption("drmMagicKey"); + } } return 0; @@ -686,6 +693,9 @@ namespace Cicada { // (int) mCurSeg->encryption.keyFormat.length()); } } + if (mDRMMagicKey.empty() && mSegKeySource) { + mDRMMagicKey = mSegKeySource->GetOption("drmMagicKey"); + } return 0; } @@ -994,8 +1004,9 @@ namespace Cicada { if (packet != nullptr) { // AF_LOGD("read a frame \n"); - if (mProtectedBuffer) { + if (mProtectedBuffer && !mDRMMagicKey.empty()) { packet->setProtected(); + packet->setMagicKey(mDRMMagicKey); } if (mPTracker->getStreamType() != STREAM_TYPE_MIXED) { packet->getInfo().streamIndex = 0; diff --git a/framework/demuxer/play_list/HLSStream.h b/framework/demuxer/play_list/HLSStream.h index ac20d6667..31275503d 100644 --- a/framework/demuxer/play_list/HLSStream.h +++ b/framework/demuxer/play_list/HLSStream.h @@ -216,6 +216,8 @@ namespace Cicada { bool mProtectedBuffer{false}; int64_t mLiveStartIndex{-3};//segment index to start live streams at (negative values are from the end) + + std::string mDRMMagicKey{}; }; } diff --git a/framework/demuxer/play_list/segment_decrypt/ISegDecrypter.h b/framework/demuxer/play_list/segment_decrypt/ISegDecrypter.h index f5ece43d6..75290148f 100644 --- a/framework/demuxer/play_list/segment_decrypt/ISegDecrypter.h +++ b/framework/demuxer/play_list/segment_decrypt/ISegDecrypter.h @@ -7,6 +7,7 @@ #include +#include class ISegDecrypter { public: @@ -25,6 +26,10 @@ class ISegDecrypter { virtual void SetOption(const char *key, uint8_t *buffer, int size) = 0; + virtual std::string GetOption(const std::string & key){ + return ""; + }; + virtual void flush() = 0; protected: diff --git a/mediaPlayer/SuperMediaPlayer.cpp b/mediaPlayer/SuperMediaPlayer.cpp index 25198924e..845f12b9c 100644 --- a/mediaPlayer/SuperMediaPlayer.cpp +++ b/mediaPlayer/SuperMediaPlayer.cpp @@ -598,6 +598,8 @@ int SuperMediaPlayer::SetOption(const char *key, const char *value) mSet->pixelBufferOutputFormat = atol(value); } else if (theKey == "liveStartIndex") { mSet->mOptions.set(theKey, value, options::REPLACE); + } else if (theKey == "DRMMagicKey") { + mSet->drmMagicKey = value; } return 0; @@ -1918,7 +1920,7 @@ RENDER_RESULT SuperMediaPlayer::RenderAudio() duration = getPCMFrameDuration(avafFrame->ToAVFrame()); } - if (mFrameCb && !mSecretPlayBack) { + if (mFrameCb && (!mSecretPlayBack || mDrmKeyValid)) { mFrameCb(mFrameCbUserData, avafFrame); } @@ -2125,7 +2127,7 @@ bool SuperMediaPlayer::RenderVideo(bool force_render) AF_LOGW("drop frame,master played time is %lld,video pts is %lld\n", masterPlayedTime, videoPts); videoFrame->setDiscard(true); - if (mFrameCb && !mSecretPlayBack) { + if (mFrameCb && (!mSecretPlayBack || mDrmKeyValid)) { mFrameCb(mFrameCbUserData, videoFrame.get()); } VideoRenderCallback(this, videoPts, nullptr); @@ -2219,7 +2221,7 @@ void SuperMediaPlayer::OnTimer(int64_t curTime) void SuperMediaPlayer::SendVideoFrameToRender(unique_ptr frame, bool valid) { - if (mFrameCb && !mSecretPlayBack) { + if (mFrameCb && (!mSecretPlayBack || mDrmKeyValid)) { bool rendered = mFrameCb(mFrameCbUserData, frame.get()); if (rendered) { VideoRenderCallback(this, frame->getInfo().pts, nullptr); @@ -2443,6 +2445,10 @@ int SuperMediaPlayer::ReadPacket() if (pMedia_Frame->isProtected() && !mSecretPlayBack) { AF_LOGI("SecretPlayBack\n"); mSecretPlayBack = true; + + if (!pMedia_Frame->getMagicKey().empty() && pMedia_Frame->getMagicKey() == mSet->drmMagicKey){ + mDrmKeyValid = true; + } } pFrame = pMedia_Frame.get(); @@ -2501,8 +2507,7 @@ int SuperMediaPlayer::ReadPacket() if (pFrame->getInfo().streamIndex == mCurrentVideoIndex || pFrame->getInfo().streamIndex == mWillChangedVideoStreamIndex) { - // FIXME: return non slice nal only when protected packet - if (mMediaFrameCb) { + if (mMediaFrameCb && (!pMedia_Frame->isProtected() || mDrmKeyValid)) { // TODO: change to std::unique_ptr mMediaFrameCb(mMediaFrameCbArg, pMedia_Frame, ST_TYPE_VIDEO); } @@ -2596,16 +2601,14 @@ int SuperMediaPlayer::ReadPacket() } } - //TODO : cache depends on this callback. need find another way - if (mMediaFrameCb /*&& !pMedia_Frame->isProtected()*/) { + if (mMediaFrameCb && (!pMedia_Frame->isProtected() || mDrmKeyValid)) { // TODO: change to std::unique_ptr mMediaFrameCb(mMediaFrameCbArg, pMedia_Frame, ST_TYPE_AUDIO); } mBufferController->AddPacket(move(pMedia_Frame), BUFFER_TYPE_AUDIO); } else if (pFrame->getInfo().streamIndex == mCurrentSubtitleIndex || pFrame->getInfo().streamIndex == mWillChangedSubtitleStreamIndex) { - //TODO : cache depends on this callback. need find another way - if (mMediaFrameCb /*&& !pMedia_Frame->isProtected()*/) { + if (mMediaFrameCb && (!pMedia_Frame->isProtected() || mDrmKeyValid)) { // TODO: change to std::unique_ptr mMediaFrameCb(mMediaFrameCbArg, pMedia_Frame, ST_TYPE_SUB); } @@ -3295,6 +3298,7 @@ void SuperMediaPlayer::Reset() } mSecretPlayBack = false; + mDrmKeyValid = false; } int SuperMediaPlayer::GetCurrentStreamIndex(StreamType type) diff --git a/mediaPlayer/SuperMediaPlayer.h b/mediaPlayer/SuperMediaPlayer.h index 1e1c62095..39a44509d 100644 --- a/mediaPlayer/SuperMediaPlayer.h +++ b/mediaPlayer/SuperMediaPlayer.h @@ -508,6 +508,7 @@ namespace Cicada { bool waitingForStart = false; bool mBRendingStart {false}; bool mSecretPlayBack{false}; + bool mDrmKeyValid{false}; private: diff --git a/mediaPlayer/player_types.cpp b/mediaPlayer/player_types.cpp index 872b34e5f..00015fab1 100644 --- a/mediaPlayer/player_types.cpp +++ b/mediaPlayer/player_types.cpp @@ -65,6 +65,7 @@ namespace Cicada { maxVideoRecoverSize = 300; mFastStart = true; pixelBufferOutputFormat = 0; + drmMagicKey = ""; } } diff --git a/mediaPlayer/player_types.h b/mediaPlayer/player_types.h index 3c04a6608..cc5872de3 100644 --- a/mediaPlayer/player_types.h +++ b/mediaPlayer/player_types.h @@ -64,6 +64,7 @@ namespace Cicada { int maxVideoRecoverSize; bool mFastStart{true}; uint32_t pixelBufferOutputFormat; + string drmMagicKey; }; }