10 #include "gst/video/gstvideotimecode.h"
11 #include "gst/video/gstvideometa.h"
14 #define USEC_PER_SEC 1000000
15 static inline uint64_t GetCurrentTimeStampInUSec()
17 struct timeval timeStamp;
20 gettimeofday(&timeStamp, NULL);
23 retVal = (uint64_t)(((uint64_t) timeStamp.tv_sec * USEC_PER_SEC) + timeStamp.tv_usec);
28 static inline uint64_t GetCurrentTimeStampInMSec()
30 return GetCurrentTimeStampInUSec() / 1000;
33 #define LOG_DECRYPT_STATS 1
34 #define DECRYPT_AVG_TIME_THRESHOLD 10.0 //10 milliseconds
35 #ifdef LOG_DECRYPT_STATS
36 #define MAX_THREADS 10
45 uint64_t nBytesInterval;
46 uint64_t nTimeInterval;
53 #endif // LOG_DECRYPT_STATS
54 #define SEC_SIZE size_t
55 void LogPerformanceExt(
const char *strFunc, uint64_t msStart, uint64_t msEnd, SEC_SIZE nDataSize)
57 uint64_t delta = msEnd - msStart;
60 #ifdef LOG_DECRYPT_STATS
64 while (idx < MAX_THREADS)
66 if (stats[idx].threadID == pthread_self())
72 if (idx == MAX_THREADS)
76 while (idx < MAX_THREADS)
78 if (stats[idx].threadID == 0)
81 stats[idx].threadID = pthread_self();
87 if (idx == MAX_THREADS)
89 printf(
"%s >>>>>>>> All slots allocated!!!, idx = %d, clearing the array.\n", __FUNCTION__, idx);
96 stats[idx].nBytesInterval += (uint64_t) nDataSize;
97 stats[idx].nTimeInterval += delta;
98 stats[idx].nCallsTotal++;
100 if (stats[idx].nCallsTotal % INTERVAL == 0)
102 stats[idx].nBytesTotal += stats[idx].nBytesInterval;
103 stats[idx].nTimeTotal += stats[idx].nTimeInterval;
104 double avgTime = (double) stats[idx].nTimeTotal / (
double) stats[idx].nCallsTotal;
105 if (avgTime >= DECRYPT_AVG_TIME_THRESHOLD)
107 logprintf(
"%s >>>>>>>> Thread ID %X (%d) Avg Time %0.2llf ms, Avg Bytes %llu calls (%llu) Interval avg time %0.2llf, Interval avg bytes %llu",
108 strFunc, stats[idx].threadID, idx, avgTime, stats[idx].nBytesTotal / stats[idx].nCallsTotal, stats[idx].nCallsTotal, (
double) stats[idx].nTimeInterval / (
double) INTERVAL, stats[idx].nBytesInterval / INTERVAL);
110 stats[idx].nBytesInterval = 0;
111 stats[idx].nTimeInterval = 0;
116 #endif //LOG_DECRYPT_STATS
126 BitStreamState(
const BitStreamState &L):
128 bit_offset(L.bit_offset) {}
129 BitStreamState & operator=(
const BitStreamState &L)
132 bit_offset = L.bit_offset;
135 BitStreamState(
const guint8 *ptr ):
143 this->bit_offset = 0;
146 int Read(
int bit_count = 1 )
149 while( bit_count-- && ptr)
152 int mask = 0x80>>(bit_offset&0x7);
153 if( ptr[bit_offset/8] & mask )
166 void AAMPOCDMGSTSessionAdapter::ExtractSEI( GstBuffer *buffer)
173 gst_buffer_map( buffer, &info, (GstMapFlags)(GST_MAP_READ) );
179 logprintf(
"Invalid Buffer Input - NULL");
180 gst_buffer_unmap(buffer, &info);
187 for(
int i=0; i<len-4; i++ )
189 if( ptr[i+0] == 0x00 &&
194 BitStreamState bitstream(&ptr[i+4]);
195 int forbidden_zero_bit = bitstream.Read();
196 int NALUnitTpe = bitstream.Read(6);
197 if( NALUnitTpe == 39 )
199 int nuh_layer_id = bitstream.Read(6);
200 int nuh_temporal_id_plus1 = bitstream.Read(3);
201 int payload_type = bitstream.Read(8);
202 if( payload_type == 136 )
204 int payload_size = bitstream.Read(8);
205 int num_clock_ts = bitstream.Read(2 );
206 for(
int j=0; j<num_clock_ts; j++ )
208 int clock_time_stamp_flag = bitstream.Read(1 );
209 if( clock_time_stamp_flag )
211 int nuit_field_based_flag = bitstream.Read();
212 int counting_type = bitstream.Read(5);
213 int full_timestamp_flag = bitstream.Read();
214 int discontinuity_flag = bitstream.Read();
215 int cnt_dropped_flag = bitstream.Read();
216 int n_frames = bitstream.Read(9);
217 int seconds_value = 0;
218 int minutes_value = 0;
220 if(full_timestamp_flag )
222 seconds_value = bitstream.Read(6);
223 minutes_value = bitstream.Read(6);
224 hours_value = bitstream.Read(5);
228 int seconds_flag = bitstream.Read();
231 seconds_value = bitstream.Read(6);
232 int minutes_flag = bitstream.Read();
235 minutes_value = bitstream.Read(6);
236 int hours_flag = bitstream.Read();
239 hours_value = bitstream.Read(5);
244 AAMPLOG_TRACE(
"SEI (HH:MM:SS) %02d:%02d:%02d number of frames (%d)", hours_value, minutes_value, seconds_value, n_frames );
245 gst_buffer_add_video_time_code_meta_full(
250 GST_VIDEO_TIME_CODE_FLAGS_NONE,
266 gst_buffer_unmap(buffer, &info);
277 if (m_pOpenCDMSession)
279 uint64_t start_decrypt_time;
280 uint64_t end_decrypt_time;
282 if (!verifyOutputProtection())
284 return HDCP_COMPLIANCE_CHECK_FAILURE;
291 AAMPLOG_TRACE(
"DEBUG: Extract the SEI timestamps from encrypted content.");
294 pthread_mutex_lock(&decryptMutex);
295 start_decrypt_time = GetCurrentTimeStampInMSec();
300 if (AAMPOCDMGSTSessionDecrypt && !gst_caps_is_empty(caps) && GST_IS_CAPS(caps))
303 retValue = AAMPOCDMGSTSessionDecrypt(m_pOpenCDMSession, buffer, subSamplesBuffer, subSampleCount, ivBuffer, keyIDBuffer, 0, caps);
307 retValue = opencdm_gstreamer_session_decrypt(m_pOpenCDMSession, buffer, subSamplesBuffer, subSampleCount, ivBuffer, keyIDBuffer, 0);
308 end_decrypt_time = GetCurrentTimeStampInMSec();
312 if (gst_buffer_map(keyIDBuffer, &keyIDMap, (GstMapFlags) GST_MAP_READ) ==
true)
314 uint8_t *mappedKeyID =
reinterpret_cast<uint8_t*
>(keyIDMap.data);
315 uint32_t mappedKeyIDSize =
static_cast<uint32_t
>(keyIDMap.size);
316 #ifdef USE_THUNDER_OCDM_API_0_2
317 KeyStatus keyStatus = opencdm_session_status(m_pOpenCDMSession, mappedKeyID, mappedKeyIDSize);
319 KeyStatus keyStatus = opencdm_session_status(m_pOpenCDMSession, mappedKeyID,mappedKeyIDSize );
321 AAMPLOG_INFO(
"AAMPOCDMSessionAdapter: decrypt returned : %d key status is : %d", retValue, keyStatus);
322 #ifdef USE_THUNDER_OCDM_API_0_2
323 if (keyStatus == OutputRestricted){
325 if(keyStatus == KeyStatus::OutputRestricted){
327 retValue = HDCP_OUTPUT_PROTECTION_FAILURE;
329 #ifdef USE_THUNDER_OCDM_API_0_2
330 else if (keyStatus == OutputRestrictedHDCP22){
332 else if(keyStatus == KeyStatus::OutputRestrictedHDCP22){
334 retValue = HDCP_COMPLIANCE_CHECK_FAILURE;
336 gst_buffer_unmap(keyIDBuffer, &keyIDMap);
341 if (gst_buffer_map(buffer, &mapInfo, GST_MAP_READ))
343 if (mapInfo.size > 0)
345 LogPerformanceExt(__FUNCTION__, start_decrypt_time, end_decrypt_time, mapInfo.size);
347 gst_buffer_unmap(buffer, &mapInfo);
350 pthread_mutex_unlock(&decryptMutex);
359 if (m_pOpenCDMSession)
361 uint64_t start_decrypt_time;
362 uint64_t end_decrypt_time;
364 if (!verifyOutputProtection())
366 return HDCP_COMPLIANCE_CHECK_FAILURE;
369 pthread_mutex_lock(&decryptMutex);
370 start_decrypt_time = GetCurrentTimeStampInMSec();
371 retValue = opencdm_session_decrypt(m_pOpenCDMSession, (uint8_t *)payloadData, payloadDataSize, f_pbIV, f_cbIV, NULL, 0, 0);
372 end_decrypt_time = GetCurrentTimeStampInMSec();
375 #ifdef USE_THUNDER_OCDM_API_0_2
376 KeyStatus keyStatus = opencdm_session_status(m_pOpenCDMSession, NULL, 0);
378 KeyStatus keyStatus = opencdm_session_status(m_pOpenCDMSession, NULL, 0);
380 AAMPLOG_INFO(
"AAMPOCDMSessionAdapter:%s : decrypt returned : %d key status is : %d", __FUNCTION__, retValue, keyStatus);
381 #ifdef USE_THUNDER_OCDM_API_0_2
382 if (keyStatus == OutputRestricted){
384 if(keyStatus == KeyStatus::OutputRestricted){
386 retValue = HDCP_OUTPUT_PROTECTION_FAILURE;
388 #ifdef USE_THUNDER_OCDM_API_0_2
389 else if (keyStatus == OutputRestrictedHDCP22){
391 else if(keyStatus == KeyStatus::OutputRestrictedHDCP22){
393 retValue = HDCP_COMPLIANCE_CHECK_FAILURE;
397 pthread_mutex_unlock(&decryptMutex);