33 #include <sys/utsname.h>
37 #define USEC_PER_SEC 1000000
40 static inline uint64_t GetCurrentTimeStampInUSec()
42 struct timeval timeStamp;
45 gettimeofday(&timeStamp, NULL);
48 retVal = (uint64_t)(((uint64_t)timeStamp.tv_sec * USEC_PER_SEC) + timeStamp.tv_usec);
54 static inline uint64_t GetCurrentTimeStampInMSec()
56 return GetCurrentTimeStampInUSec() / 1000;
59 #define LOG_DECRYPT_STATS 1
60 #define DECRYPT_AVG_TIME_THRESHOLD 10.0 //10 milliseconds
61 #ifdef LOG_DECRYPT_STATS
62 #define MAX_THREADS 10
71 uint64_t nBytesInterval;
72 uint64_t nTimeInterval;
79 #endif // LOG_DECRYPT_STATS
80 #define SEC_SIZE size_t
83 void LogPerformanceExt(
const char* strFunc, uint64_t msStart, uint64_t msEnd, SEC_SIZE nDataSize)
85 bool bThreshold =
false;
86 uint64_t delta = msEnd - msStart;
87 uint32_t nRateMin = 1000;
88 uint32_t nRestart = 5;
89 uint32_t nDataMin = 1000;
90 uint32_t nTimeMin = 5;
92 #ifdef LOG_DECRYPT_STATS
96 while(idx < MAX_THREADS) {
97 if(stats[idx].threadID == pthread_self()) {
102 if(idx == MAX_THREADS) {
105 while(idx < MAX_THREADS) {
106 if(stats[idx].threadID == 0) {
108 stats[idx].threadID = pthread_self();
114 if(idx == MAX_THREADS) {
115 AAMPLOG_WARN(
">>>>>>>> All slots allocated!!!, idx = %d, clearing the array.", idx);
121 stats[idx].nBytesInterval += (uint64_t)nDataSize;
122 stats[idx].nTimeInterval += delta;
123 stats[idx].nCallsTotal++;
125 if(stats[idx].nCallsTotal % INTERVAL == 0) {
126 stats[idx].nBytesTotal += stats[idx].nBytesInterval;
127 stats[idx].nTimeTotal += stats[idx].nTimeInterval;
128 double avgTime = (double)stats[idx].nTimeTotal/(
double)stats[idx].nCallsTotal;
129 if(avgTime >= DECRYPT_AVG_TIME_THRESHOLD) {
130 AAMPLOG_WARN(
">>>>>>>> Thread ID %X (%d) Avg Time %0.2llf ms, Avg Bytes %llu calls (%llu) Interval avg time %0.2llf, Interval avg bytes %llu",
131 strFunc, stats[idx].threadID, idx, avgTime, stats[idx].nBytesTotal/stats[idx].nCallsTotal,
132 stats[idx].nCallsTotal, (
double)stats[idx].nTimeInterval/(
double)INTERVAL,
133 stats[idx].nBytesInterval/INTERVAL);
135 stats[idx].nBytesInterval = 0;
136 stats[idx].nTimeInterval = 0;
141 #endif //LOG_DECRYPT_STATS
145 #include "b_secbuf.h"
151 struct Rpc_Secbuf_Info {
160 #define USE_NEW_OPENCDM 1
162 AAMPOCDMSession::AAMPOCDMSession(
AampLogManager *logObj,
const string& keySystem) :
165 m_pOutputProtection(NULL),
167 m_pOpencdmDecrypt(NULL),
172 pthread_mutex_init(&decryptMutex,NULL);
174 initAampDRMSession();
182 void AAMPOCDMSession::initAampDRMSession()
185 if (m_pOpencdm == NULL) {
186 m_pOpencdm =
new media::OpenCdm();
189 m_pOpencdm->SelectKeySystem(m_keySystem);
195 uint32_t f_cbInitData, std::string &customData)
198 pthread_mutex_lock(&decryptMutex);
200 m_sessionID = m_pOpencdm->CreateSession(
"video/mp4",
const_cast<unsigned char*
>(f_pbInitData), f_cbInitData, media::OpenCdm::Temporary);
201 AAMPLOG_WARN(
"generateAampDRMSession :: sessionId : %s ", m_sessionID.c_str());
202 if(m_sessionID.empty()) {
206 std::string sessionId;
207 m_pOpencdm->CreateSession(
"video/mp4",
const_cast<unsigned char*
>(f_pbInitData), f_cbInitData, sessionId);
208 AAMPLOG_WARN(
"generateAampDRMSession :: sessionId : %s ", sessionId.c_str());
209 if(sessionId.empty()) {
213 pthread_mutex_unlock(&decryptMutex);
217 AAMPOCDMSession::~AAMPOCDMSession()
219 AAMPLOG_WARN(
"[HHH]OCDMSession destructor called! keySystem %s", m_keySystem.c_str());
222 pthread_mutex_destroy(&decryptMutex);
224 if(m_pOpencdmDecrypt)
226 m_pOpencdmDecrypt->Close();
227 SAFE_DELETE(m_pOpencdmDecrypt);
233 #if USE_NEW_OPENCDM<1
234 m_pOpencdm->ReleaseMem();
237 SAFE_DELETE(m_pOpencdm);
241 if(m_pOutputProtection)
243 m_pOutputProtection->Release();
252 std::string challenge;
253 int challengeLength = 0;
254 pthread_mutex_lock(&decryptMutex);
257 unsigned char temporaryUrl[1024] = {
'\0'};
258 uint16_t destinationUrlLength =
sizeof(temporaryUrl);
260 m_pOpencdm->GetKeyMessage(challenge, temporaryUrl, destinationUrlLength);
261 if (challenge.empty() || !destinationUrlLength) {
263 AAMPLOG_WARN(
"aampGenerateKeyRequest :: challenge or URL is empty. ");
264 pthread_mutex_unlock(&decryptMutex);
269 std::string delimiter (
":Type:");
270 std::string requestType (challenge.substr(0, challenge.find(delimiter)));
272 if ( (requestType.size() != 0) && (requestType.size() != challenge.size()) ) {
273 challenge.erase(0, challenge.find(delimiter) + delimiter.length());
276 result =
new DrmData(
reinterpret_cast<unsigned char*
>(
const_cast<char*
>(challenge.c_str())), challenge.length());
277 destinationURL.assign(
const_cast<char*
>(
reinterpret_cast<char*
>(temporaryUrl)));
278 AAMPLOG_WARN(
"destination url is %s", destinationURL.c_str());
280 unsigned char temporaryUrl[1024] = {
'\0'};
281 int destinationUrlLength = 0;
283 m_pOpencdm->GetKeyMessage(challenge, &challengeLength,
284 temporaryUrl, &destinationUrlLength);
286 if (!challengeLength || !destinationUrlLength) {
288 AAMPLOG_WARN(
"aampGenerateKeyRequest :: challenge or URL is empty. ");
289 pthread_mutex_unlock(&decryptMutex);
293 result =
new DrmData(
reinterpret_cast<unsigned char*
>(
const_cast<char*
>(challenge.c_str())), challengeLength);
294 destinationURL.assign(
const_cast<char*
>(
reinterpret_cast<char*
>(temporaryUrl)));
295 AAMPLOG_WARN(
"destin url is %s", destinationURL.c_str());
299 pthread_mutex_unlock(&decryptMutex);
308 cout <<
"aampDRMProcessKey :: Playready Update" << endl;
310 pthread_mutex_lock(&decryptMutex);
311 std::string responseMessage;
312 media::OpenCdm::KeyStatus keyStatus = media::OpenCdm::KeyStatus::InternalError;
313 std::string message = key ? key->
getData():
"";
314 const uint8_t* keyMessage =
reinterpret_cast<const uint8_t*
>(&message[0]);
315 const uint16_t keyMessageLength = key ? key->
getDataLength():0;
319 keyStatus = m_pOpencdm->Update(keyMessage, keyMessageLength, responseMessage);
323 keyStatus = m_pOpencdm->Status();
326 retvalue = (int)keyStatus;
327 if (keyStatus == media::OpenCdm::KeyStatus::Usable)
329 AAMPLOG_WARN(
"processKey: Key Usable!");
331 else if(keyStatus == media::OpenCdm::KeyStatus::HWError)
334 AAMPLOG_WARN(
"processKey: Update() returned HWError.Restarting process...");
335 int systemResult = -1;
338 systemResult = system(
"pgrep WPEcdmi");
339 if(systemResult == 0)
341 systemResult = system(
"pkill -9 WPEcdmi");
342 if(systemResult != 0)
344 AAMPLOG_WARN(
"Unable to shutdown WPEcdmi process.%d", systemResult);
350 systemResult = system(
"pgrep WPEFramework");
351 if(systemResult == 0)
353 systemResult = system(
"pkill -9 WPEFramework");
354 if(systemResult != 0)
356 AAMPLOG_WARN(
"Unable to shutdown WPEFramework process.%d", systemResult);
364 pid_t pid = getpid();
365 syscall(__NR_tgkill, pid, pid, SIGKILL);
369 if(keyStatus == media::OpenCdm::KeyStatus::OutputRestricted)
371 AAMPLOG_WARN(
"processKey: Update() Output restricted keystatus: %d", (
int) keyStatus);
372 retvalue = HDCP_OUTPUT_PROTECTION_FAILURE;
374 else if(keyStatus == media::OpenCdm::KeyStatus::OutputRestrictedHDCP22)
376 AAMPLOG_WARN(
"processKey: Update() Output Compliance error keystatus: %d", (
int) keyStatus);
377 retvalue = HDCP_COMPLIANCE_CHECK_FAILURE;
381 AAMPLOG_WARN(
"processKey: Update() returned keystatus: %d", (
int) keyStatus);
384 pthread_mutex_unlock(&decryptMutex);
390 m_pOpencdmDecrypt =
new media::OpenCdm(m_sessionID);
392 pthread_mutex_unlock(&decryptMutex);
398 const uint8_t *payloadData, uint32_t payloadDataSize, uint8_t **ppOpaqueData)
401 struct Rpc_Secbuf_Info sb_info;
404 uint64_t start_decrypt_time;
405 uint64_t end_decrypt_time;
407 *ppOpaqueData = NULL;
410 if(!m_pOpencdmDecrypt)
412 AAMPLOG_WARN(
"m_pOpencdmDecrypt is NULL, can't decrypt yet!");
421 if((m_keySystem == PLAYREADY_KEY_SYSTEM_STRING && m_OutputProtectionEnabled) && m_pOutputProtection->
IsSourceUHD()) {
425 AAMPLOG_ERR(
" UHD source but not HDCP 2.2. FAILING decrypt");
426 return HDCP_COMPLIANCE_CHECK_FAILURE;
430 pthread_mutex_lock(&decryptMutex);
431 start_decrypt_time = GetCurrentTimeStampInMSec();
433 retvalue = m_pOpencdmDecrypt->Decrypt(
const_cast<unsigned char*
>(payloadData), payloadDataSize, f_pbIV, f_cbIV);
435 retvalue = m_pOpencdm->Decrypt(
const_cast<unsigned char*
>(payloadData), payloadDataSize,
const_cast<unsigned char*
>(f_pbIV), f_cbIV);
437 end_decrypt_time = GetCurrentTimeStampInMSec();
440 media::OpenCdm::KeyStatus keyStatus = m_pOpencdm->Status();
441 AAMPLOG_INFO(
"decrypt returned : %d key status is : %d", retvalue,keyStatus);
442 if(keyStatus == media::OpenCdm::KeyStatus::OutputRestricted){
443 retvalue = HDCP_OUTPUT_PROTECTION_FAILURE;
445 else if(keyStatus == media::OpenCdm::KeyStatus::OutputRestrictedHDCP22){
446 retvalue = HDCP_COMPLIANCE_CHECK_FAILURE;
449 if(payloadDataSize > 0) {
450 LogPerformanceExt(__FUNCTION__, start_decrypt_time, end_decrypt_time, payloadDataSize);
453 pthread_mutex_unlock(&decryptMutex);
457 memcpy(&sb_info, payloadData,
sizeof(Rpc_Secbuf_Info));
458 if (B_Secbuf_AllocWithToken(sb_info.size, (B_Secbuf_Type)sb_info.type, sb_info.token, (
void **)ppOpaqueData))
460 AAMPLOG_ERR(
"[HHH] B_Secbuf_AllocWithToken() failed!");
477 AAMPLOG_WARN(
"[HHH] clearDecryptContext.");
478 pthread_mutex_lock(&decryptMutex);
480 #if USE_NEW_OPENCDM < 1
481 if(m_pOpencdm) m_pOpencdm->ReleaseMem();
483 SAFE_DELETE(m_pOpencdmDecrypt);
485 if(m_pOpencdm) m_pOpencdm->Close();
487 pthread_mutex_unlock(&decryptMutex);