diff options
Diffstat (limited to 'videocodec')
| -rw-r--r-- | videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.cpp | 497 | ||||
| -rw-r--r-- | videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.h | 114 | ||||
| -rw-r--r-- | videocodec/securevideo/baytrail/widevine.h | 9 |
3 files changed, 475 insertions, 145 deletions
diff --git a/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.cpp b/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.cpp index 453a680..7ca2a53 100644 --- a/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.cpp +++ b/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.cpp @@ -33,6 +33,7 @@ static const char* AVC_SECURE_MIME_TYPE = "video/avc-secure"; OMXVideoDecoderAVCSecure::OMXVideoDecoderAVCSecure() : mpLibInstance(NULL), + mPAVPAppID(0xFF), mDropUntilIDR(false) { LOGV("OMXVideoDecoderAVCSecure is constructed."); mVideoDecoder = createVideoDecoder(AVC_SECURE_MIME_TYPE); @@ -122,6 +123,291 @@ OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareConfigBuffer(VideoConfigBuffer *p return ret; } +// Temp placeholder for NALU merge +static uint8_t config_nalu[1024]; +static uint32_t config_nalu_len; +// Merge NALU for config (SPS & PPS) with Slice data for MDRM. +static void update_config_nalu(uint8_t* nalu_data, uint32_t* nalu_size) +{ + //move NALU for encrypted portion behind config info + uint8_t temp[1024]; + memset(temp, 0, 1024); + + uint32_t* enc_dword_ptr = NULL; + uint32_t enc_num_nalus = 0; + uint32_t* clr_dword_ptr = NULL; + uint32_t clr_num_nalus = 0; + + if (*nalu_size > 4) { + memcpy(temp, nalu_data+4, ((*nalu_size)-4)); + } else { + LOGI("%s: NALU size < 4!"); + return; + } + + enc_dword_ptr = (uint32_t*)nalu_data; + enc_num_nalus = bswap_32(*enc_dword_ptr); + clr_dword_ptr = (uint32_t*)config_nalu; + clr_num_nalus = bswap_32(*clr_dword_ptr); + + enc_dword_ptr = (uint32_t*)(config_nalu + (config_nalu_len-16)); + (*enc_dword_ptr) = bswap_32(0); + //copy config nalu + memcpy(nalu_data, config_nalu, config_nalu_len); + // ignore first 4 len bytes + memcpy((nalu_data + config_nalu_len), temp, ((*nalu_size)-4)); + + enc_dword_ptr = (uint32_t*)nalu_data; + (*enc_dword_ptr) = bswap_32(enc_num_nalus + clr_num_nalus); + enc_num_nalus = (*enc_dword_ptr); + *nalu_size = ((*nalu_size) + config_nalu_len - 4); + + enc_dword_ptr = (uint32_t*)nalu_data; + enc_dword_ptr++; + (*enc_dword_ptr) = bswap_32(0); + +} +// Create PAVP Session & retrieve associated PAVP AppID. +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::CreatePavpSession(void) { + if(!mpLibInstance) { + LOGE("mpLibInstance is NULL!"); + return OMX_ErrorNotReady; + } + pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; + + LOGI("PAVP Heavy session creation..."); + + rc = mpLibInstance->pavp_create_session(true); + if (rc != pavp_lib_session::status_ok) { + LOGE("PAVP Heavy: pavp_create_session failed with error 0x%x", rc); + return OMX_ErrorNotReady; + } + + LOGI("Get AppId of the PAVP Heavy session..."); + + rc = mpLibInstance->pavp_get_app_id(reinterpret_cast<UINT&>(mPAVPAppID)); + if (rc != pavp_lib_session::status_ok) { + LOGE("PAVP Heavy: pavp_get_app_id failed with error 0x%x", rc); + return OMX_ErrorNotReady; + } else { + LOGE("pavp_get_app_id succesful, uiAppId = 0x%x", mPAVPAppID); + } + return OMX_ErrorNone; +} +//PAVP SecPassThrough to communicate with SEC. +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SecPassThrough(uint8_t* pInput, uint32_t inSize, uint8_t* pOutput, uint32_t outSize) { + + pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; + + if(!mpLibInstance) { + LOGE("mpLibInstance is NULL!"); + return OMX_ErrorNotReady; + } + + rc = mpLibInstance->sec_pass_through( + reinterpret_cast<BYTE*>(pInput), + inSize, + reinterpret_cast<BYTE*>(pOutput), + outSize); + + if (rc != pavp_lib_session::status_ok) { + LOGE("PAVP Failed: 0x%x", rc); + return OMX_ErrorNotReady; + } + PAVP_CMD_HEADER *pHeader = (PAVP_CMD_HEADER*)pOutput; + if (pHeader->Status) { + LOGE("SEC failed: wv_set_xcript_key() FAILED 0x%x", pHeader->Status); + return OMX_ErrorNotReady; + } + return OMX_ErrorNone; +} + +// MDRM - Key injection +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::MdrmInjectKey(uint8_t in_session_id, uint8_t* in_key_id) { + LOGV("%s", __FUNCTION__); + if(!mpLibInstance) { + LOGE("mpLibInstance is NULL!"); + return OMX_ErrorNotReady; + } + wv2_inject_key_in input; + wv2_inject_key_out output; + transcript_conf conf; + + conf.drm_type_1_0 = 2;//PR 1 //SS + conf.dest_encrypt_mode_25_24 = 1;//PR 0 + + input.conf = conf; + input.Header.ApiVersion = 0x00010005; + input.Header.CommandId = wv2_inject_key; + input.Header.Status = 0; + input.Header.BufferLength = sizeof(input)-sizeof(PAVP_CMD_HEADER); + input.session_id = in_session_id; + input.StreamId = mPAVPAppID; + memcpy(input.key_id, in_key_id, 16); + + return SecPassThrough((uint8_t*)&input, sizeof(input), (uint8_t*)&output, sizeof(output)); +} + +// Classic - Key injection +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::WvSetTranscriptKey(void) { + LOGV("%s", __FUNCTION__); + if(!mpLibInstance) { + LOGE("mpLibInstance is NULL!"); + return OMX_ErrorNotReady; + } + wv_set_xcript_key_in input; + wv_set_xcript_key_out output; + + input.Header.ApiVersion = WV_API_VERSION; + input.Header.CommandId = wv_set_xcript_key; + input.Header.Status = 0; + input.StreamId = mPAVPAppID; + input.Header.BufferLength = sizeof(input)-sizeof(PAVP_CMD_HEADER); + + return SecPassThrough((uint8_t*)&input, sizeof(input), (uint8_t*)&output, sizeof(output)); +} + +//Classic ProcessVideoFrame +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ClassicProcessVideoFrame(SECVideoBuffer *secBuffer, uint32_t *parsed_data_size) { + OMX_ERRORTYPE ret = OMX_ErrorNone; + + LOGV("%s", __FUNCTION__); + + if(!mpLibInstance) { + LOGE("mpLibInstance is NULL!"); + return OMX_ErrorNotReady; + } + + wv_heci_process_video_frame_in input; + wv_heci_process_video_frame_out output; + + pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; + input.Header.ApiVersion = WV_API_VERSION; + input.Header.CommandId = wv_process_video_frame; + input.Header.Status = 0; + input.Header.BufferLength = sizeof(input) - sizeof(PAVP_CMD_HEADER); + input.num_of_packets = secBuffer->pes_packet_count; + input.is_frame_not_encrypted = secBuffer->clear; + input.src_offset = secBuffer->base_offset + secBuffer->partitions.src.offset; + input.dest_offset = secBuffer->base_offset + secBuffer->partitions.dest.offset; + input.metadata_offset = secBuffer->base_offset + secBuffer->partitions.metadata.offset; + input.header_offset = secBuffer->base_offset + secBuffer->partitions.headers.offset; + + memset(&output, 0, sizeof(wv_heci_process_video_frame_out)); + + ret = SecPassThrough((uint8_t*)&input, sizeof(input), (uint8_t*)&output, sizeof(output)); + *parsed_data_size = output.parsed_data_size; + memcpy(secBuffer->iv, output.iv, 16); + secBuffer->mdrm_info.config_len = 0; + + return ret; +} + +//MDRM ProcessVideoFrame +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ModularProcessVideoFrame(SECVideoBuffer *secBuffer, uint32_t *parsed_data_size) { + OMX_ERRORTYPE ret = OMX_ErrorNone; + LOGV("%s", __FUNCTION__); + if(!mpLibInstance) { + LOGE("mpLibInstance is NULL!"); + return OMX_ErrorNotReady; + } + + wv2_process_video_frame_in input; + wv2_process_video_frame_out output; + transcript_conf conf; + memset(&conf, 0, sizeof(conf)); + memset(&input, 0, sizeof(input)); + memset(&output, 0, sizeof(wv2_process_video_frame_out)); + + input.Header.ApiVersion = 0x00010005; + input.Header.CommandId = wv2_process_video_frame; + input.Header.Status = 0; + input.Header.BufferLength = sizeof(input) - sizeof(PAVP_CMD_HEADER); + + memcpy(input.key_id, secBuffer->mdrm_info.key_id, 16); + input.key_id_len = secBuffer->mdrm_info.key_id_len; + input.session_id = secBuffer->mdrm_info.session_id; //mSessionID? + input.header_offset = secBuffer->base_offset + secBuffer->partitions.headers.offset; + input.dest_offset = secBuffer->base_offset + secBuffer->partitions.dest.offset; + + conf.drm_type_1_0 = 2;//PR 1 //SS + conf.dest_encrypt_mode_25_24 = 1;//PR 0 + if ( secBuffer->mdrm_info.config_len) { + memset(config_nalu, 0, sizeof(config_nalu)); + pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; + conf.num_headers_or_packets_15_8 = 2; //SPS/PPS + conf.src_encrypt_mode_17_16 = 0;//clear=0;//PR 1 + input.conf = conf; + input.frame_offset = secBuffer->base_offset + secBuffer->partitions.src.offset; + input.metadata_offset = secBuffer->base_offset + secBuffer->partitions.metadata.offset; + + ret = SecPassThrough((uint8_t*)&input, sizeof(input), (uint8_t*)&output, sizeof(output)); + + if(ret == OMX_ErrorNone) { + // Assemble parsed frame information + // NALU data + uint8_t *nalu_data = secBuffer->base + secBuffer->partitions.headers.offset; + uint32_t nalu_data_size = output.parsed_data_size; + memcpy(config_nalu, nalu_data, nalu_data_size); + config_nalu_len = nalu_data_size; + } + } + + if ( ret == OMX_ErrorNone) { + conf.num_headers_or_packets_15_8 = secBuffer->pes_packet_count; //SS + conf.src_encrypt_mode_17_16 = secBuffer->clear?0:1;//clear=0;//PR 1 + input.conf = conf; + + if (secBuffer->mdrm_info.config_len) { + input.metadata_offset =SEC_DMA_ALIGN( secBuffer->base_offset + secBuffer->partitions.metadata.offset + 24); + input.frame_offset = secBuffer->mdrm_info.config_frame_offset; + } else { + input.frame_offset = secBuffer->base_offset + secBuffer->partitions.src.offset; + input.metadata_offset = secBuffer->base_offset + secBuffer->partitions.metadata.offset; + } + ret = SecPassThrough((uint8_t*)&input, sizeof(input), (uint8_t*)&output, sizeof(output)); + *parsed_data_size = output.parsed_data_size; + } + secBuffer->pes_packet_count = 0; + return ret; +} + +// Manage PAVP Session - destroy & re-create for Auto-tear-down +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ManagePAVPSession(bool force_recreate) { + LOGV("%s", __FUNCTION__); + + // PAVP auto teardown: check if PAVP session is alive + bool balive = false; + pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; + rc = mpLibInstance->pavp_is_session_alive(&balive); + if (rc != pavp_lib_session::status_ok) { + LOGE("pavp_is_session_alive failed with error 0x%x", rc); + return OMX_ErrorNotReady; + } + + if (!balive || force_recreate) { + + LOGI("PAVP session is %s", balive?"active":"in-active"); + //Destroy & re-create + LOGI("Destroying the PAVP session..."); + rc = mpLibInstance->pavp_destroy_session(); + if (rc != pavp_lib_session::status_ok) { + LOGE("pavp_destroy_session failed with error 0x%x", rc); + return OMX_ErrorNotReady; + } + + // Frames in the video decoder DPB are encrypted with the + // PAVP heavy mode key (IED key) for the destroyed session. + // Flush video decoder to remove them. + mVideoDecoder->flush(); + + mpLibInstance = NULL; + mDropUntilIDR = true; + } + return OMX_ErrorNone; + +} + OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { OMX_ERRORTYPE ret; ret = OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); @@ -130,12 +416,6 @@ OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE if (buffer->nFilledLen == 0) { return OMX_ErrorNone; } - // OMX_BUFFERFLAG_CODECCONFIG is an optional flag - // if flag is set, buffer will only contain codec data. - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { - LOGV("Received AVC codec data."); - return ret; - } p->flag |= HAS_COMPLETE_FRAME; if (buffer->nOffset != 0) { @@ -153,161 +433,88 @@ OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE return OMX_ErrorBadParameter; } - pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; - - if(!mpLibInstance && secBuffer->pLibInstance) { - LOGE("PAVP Heavy session creation..."); - rc = secBuffer->pLibInstance->pavp_create_session(true); - if (rc != pavp_lib_session::status_ok) { - LOGE("PAVP Heavy: pavp_create_session failed with error 0x%x", rc); - ret = OMX_ErrorNotReady; - } else { - LOGE("PAVP Heavy session created succesfully"); - mpLibInstance = secBuffer->pLibInstance; - } - if ( ret == OMX_ErrorNone) { - pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; - wv_set_xcript_key_in input; - wv_set_xcript_key_out output; - - input.Header.ApiVersion = WV_API_VERSION; - input.Header.CommandId = wv_set_xcript_key; - input.Header.Status = 0; - input.Header.BufferLength = sizeof(input)-sizeof(PAVP_CMD_HEADER); - - - if (secBuffer->pLibInstance) { - LOGV("calling wv_set_xcript_key"); - rc = secBuffer->pLibInstance->sec_pass_through( - reinterpret_cast<BYTE*>(&input), - sizeof(input), - reinterpret_cast<BYTE*>(&output), - sizeof(output)); - LOGV("wv_set_xcript_key returned %d", rc); - } - - if (rc != pavp_lib_session::status_ok) - LOGE("sec_pass_through:wv_set_xcript_key() failed with error 0x%x", rc); - - if (output.Header.Status) { - LOGE("SEC failed: wv_set_xcript_key() FAILED 0x%x", output.Header.Status); - ret = OMX_ErrorNotReady; - } - } + // OMX_BUFFERFLAG_CODECCONFIG is an optional flag + // if flag is set, buffer will only contain codec data. + if ( (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) && + (secBuffer->drm_type == DRM_TYPE_CLASSIC_WV)) { + LOGV("Received AVC codec data."); + return ret; } - if(mpLibInstance) { - // PAVP auto teardown: check if PAVP session is alive - bool balive = false; - pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; - rc = mpLibInstance->pavp_is_session_alive(&balive); - if (rc != pavp_lib_session::status_ok) { - LOGE("pavp_is_session_alive failed with error 0x%x", rc); - } + uint32_t parsed_data_size = 0; - if (balive == false || (ret == OMX_ErrorNotReady)) { + if(secBuffer->drm_type == DRM_TYPE_CLASSIC_WV) { - LOGE("PAVP session is %s", balive?"active":"in-active"); - ret = OMX_ErrorNotReady; - //Destroy & re-create - LOGI("Destroying the PAVP session..."); - rc = mpLibInstance->pavp_destroy_session(); - if (rc != pavp_lib_session::status_ok) - LOGE("pavp_destroy_session failed with error 0x%x", rc); - - // Frames in the video decoder DPB are encrypted with the - // PAVP heavy mode key (IED key) for the destroyed session. - // Flush video decoder to remove them. - mVideoDecoder->flush(); + if(!mpLibInstance && secBuffer->pLibInstance) { + mpLibInstance = secBuffer->pLibInstance; + if( CreatePavpSession() == OMX_ErrorNone) { + ret = WvSetTranscriptKey(); + } + } + ret = ManagePAVPSession(ret == OMX_ErrorNotReady); - mpLibInstance = NULL; - mDropUntilIDR = true; + if ( ret == OMX_ErrorNone) { + ret = ClassicProcessVideoFrame(secBuffer, &parsed_data_size); } } + else if(secBuffer->drm_type == DRM_TYPE_MDRM) { - wv_heci_process_video_frame_in input; - wv_heci_process_video_frame_out output; - if ( ret == OMX_ErrorNone) { - - input.Header.ApiVersion = WV_API_VERSION; - input.Header.CommandId = wv_process_video_frame; - input.Header.Status = 0; - input.Header.BufferLength = sizeof(input) - sizeof(PAVP_CMD_HEADER); - - input.num_of_packets = secBuffer->pes_packet_count; - input.is_frame_not_encrypted = secBuffer->clear; - input.src_offset = secBuffer->base_offset + secBuffer->partitions.src.offset; - input.dest_offset = secBuffer->base_offset + secBuffer->partitions.dest.offset; - input.metadata_offset = secBuffer->base_offset + secBuffer->partitions.metadata.offset; - input.header_offset = secBuffer->base_offset + secBuffer->partitions.headers.offset; - - memset(&output, 0, sizeof(wv_heci_process_video_frame_out)); - - if (secBuffer->pLibInstance) { - LOGV("calling wv_process_video_frame"); - rc = secBuffer->pLibInstance->sec_pass_through( - reinterpret_cast<BYTE*>(&input), - sizeof(input), - reinterpret_cast<BYTE*>(&output), - sizeof(output)); - LOGV("wv_process_video_frame returned %d", rc); - - if (rc != pavp_lib_session::status_ok) { - LOGE("%s PAVP Failed: 0x%x", __FUNCTION__, rc); - ret = OMX_ErrorNotReady; - } - - if (output.Header.Status != 0x0) { - LOGE("%s SEC Failed: wv_process_video_frame: 0x%x", __FUNCTION__, output.Header.Status); - ret = OMX_ErrorNotReady; + if(!mpLibInstance && secBuffer->pLibInstance) { + mpLibInstance = secBuffer->pLibInstance; + if( CreatePavpSession() == OMX_ErrorNone) { + ret = MdrmInjectKey(secBuffer->mdrm_info.session_id, secBuffer->mdrm_info.key_id); } } + ret = ManagePAVPSession(ret == OMX_ErrorNotReady); + if( ret == OMX_ErrorNone) { + ret = ModularProcessVideoFrame(secBuffer, &parsed_data_size); + } + } else { + LOGE("Invalid DRM_TYPE: 0x%x passed!", secBuffer->drm_type); + ret = OMX_ErrorNotReady; } SECParsedFrame* parsedFrame = &(mParsedFrames[secureBuffer->index]); if(ret == OMX_ErrorNone) { - // Assemble parsed frame information - - // NALU data - parsedFrame->nalu_data = secBuffer->base + secBuffer->partitions.headers.offset; - parsedFrame->nalu_data_size = output.parsed_data_size; - - // Set up PAVP info - memcpy(parsedFrame->pavp_info.iv, output.iv, WV_AES_IV_SIZE); - - // construct frame_info - ret = ConstructFrameInfo(secBuffer->base + secBuffer->partitions.dest.offset, secBuffer->frame_size, - &(parsedFrame->pavp_info), parsedFrame->nalu_data, parsedFrame->nalu_data_size, - &(parsedFrame->frame_info)); - - if (parsedFrame->frame_info.num_nalus == 0 ) { - LOGE("NALU parsing failed - num_nalus = 0!"); - ret = OMX_ErrorNotReady; - } - - if(mDropUntilIDR) { - bool idr = false; - for(uint32_t n = 0; n < parsedFrame->frame_info.num_nalus; n++) { - if((parsedFrame->frame_info.nalus[n].type & 0x1F) == h264_NAL_UNIT_TYPE_IDR) { - idr = true; - break; - } - } - if(idr) { - LOGD("IDR frame found; restoring playback."); - mDropUntilIDR = false; - } else { - LOGD("Dropping non-IDR frame."); - ret = OMX_ErrorNotReady; - } - } + // Assemble parsed frame information + // NALU data + parsedFrame->nalu_data = secBuffer->base + secBuffer->partitions.headers.offset; + parsedFrame->nalu_data_size = parsed_data_size; + if (secBuffer->mdrm_info.config_len) { + update_config_nalu(parsedFrame->nalu_data, &(parsedFrame->nalu_data_size)); + } + memcpy(parsedFrame->pavp_info.iv, secBuffer->iv, 16); + + ret = ConstructFrameInfo(secBuffer->base + secBuffer->partitions.dest.offset, buffer->nFilledLen, + &(parsedFrame->pavp_info), parsedFrame->nalu_data, parsedFrame->nalu_data_size, + &(parsedFrame->frame_info)); + + if(parsedFrame->frame_info.num_nalus == 0 ) { + LOGE("NALU parsing failed - num_nalus = 0!"); + ret = OMX_ErrorNotReady; + } + if(mDropUntilIDR) { + bool idr = false; + for(uint32_t n = 0; n < parsedFrame->frame_info.num_nalus; n++) { + if((parsedFrame->frame_info.nalus[n].type & 0x1F) == h264_NAL_UNIT_TYPE_IDR) { + idr = true; + break; + } + } + if(idr) { + LOGD("IDR frame found; restoring playback."); + mDropUntilIDR = false; + } else { + LOGD("Dropping non-IDR frame."); + ret = OMX_ErrorNotReady; + } + } } - if(ret == OMX_ErrorNone) { - // Pass frame info to VideoDecoderAVCSecure in VideoDecodeBuffer - p->data = (uint8_t *)&(parsedFrame->frame_info); - p->size = sizeof(frame_info_t); - p->flag = p->flag | IS_SECURE_DATA; + // Pass frame info to VideoDecoderAVCSecure in VideoDecodeBuffer + p->data = (uint8_t *)&(parsedFrame->frame_info); + p->size = sizeof(frame_info_t); + p->flag |= IS_SECURE_DATA; } return ret; diff --git a/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.h b/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.h index 77c2748..5c92cc7 100644 --- a/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.h +++ b/videocodec/securevideo/baytrail/OMXVideoDecoderAVCSecure.h @@ -23,6 +23,10 @@ #include "widevine.h" #include "secvideoparser.h" +#define SEC_DMA_ALIGN(x) (((x)+0x1F)&(~0x1F)) +#define DRM_TYPE_CLASSIC_WV 0x0 +#define DRM_TYPE_MDRM 0x1 + // Must match the same structs defined in WVCrypto.h #pragma pack(push, 1) typedef struct { @@ -36,6 +40,14 @@ typedef struct { sec_partition_t headers; } video_partition_t; typedef struct { + uint8_t config[64]; + uint8_t config_len; + uint32_t config_frame_offset; + uint8_t key_id[16]; + uint32_t key_id_len; + uint8_t session_id; +} mdrm_meta; +typedef struct { pavp_lib_session* pLibInstance; uint8_t* base; uint32_t size; @@ -45,6 +57,9 @@ typedef struct { uint32_t src_fill; uint8_t pes_packet_count; uint8_t clear; + mdrm_meta mdrm_info; + uint8_t drm_type; //0 -> Classic, 1 -> MDRM + uint8_t iv[16]; } SECVideoBuffer; typedef struct { uint32_t index; @@ -52,6 +67,97 @@ typedef struct { } OMXSecureBuffer; #pragma pack(pop) +//Function Codes +typedef enum { + wv2_begin = 0x000C0001, + wv2_open_session = wv2_begin, + wv2_generate_nonce, + wv2_generate_derived_keys, + wv2_generate_hmac_signature, + wv2_load_keys, + wv2_refresh_keys, + wv2_select_key, + wv2_inject_key, + wv2_rewrap_device_RSA_key, + wv2_load_device_RSA_key, + wv2_generate_RSA_signature, + wv2_derived_sessionkeys, + wv2_process_video_frame, + wv2_decrypt_ctr, + wv2_generic_encrypt, + wv2_generic_decrypt, + wv2_generic_sign, + wv2_generic_verify_signature, + wv2_close_session, + wv2_dbg_get_keys, + wv2_delete_nonce, +} wv2_heci_command_id; + + +typedef struct { + uint32_t dest_encrypt_mode_25_24 : 2; + uint32_t reserved_31_26 : 6; + uint32_t src_encrypt_mode_17_16 : 2; + uint32_t reserved_23_18 : 6; + uint32_t num_headers_or_packets_15_8 : 8; + uint32_t drm_type_1_0 : 2; + uint32_t reserved_7_2 : 6; +} transcript_conf; +/*processvidoe frame*/ +typedef struct { + PAVP_CMD_HEADER Header; + transcript_conf conf; + uint32_t key_index; + uint32_t frame_offset; + uint32_t metadata_offset; + uint32_t header_offset; + uint32_t dest_offset; + uint8_t key_id[16]; +} process_video_frame_in; +typedef struct { + PAVP_CMD_HEADER Header; + uint32_t parsed_data_size; + uint8_t key_id[16]; + uint8_t key[16]; + // uint32_t frame_size; + uint8_t iv[16]; +} process_video_frame_out; + +/*wv2_inject_key*/ +typedef struct { + PAVP_CMD_HEADER Header; + uint32_t session_id; + uint32_t StreamId; + transcript_conf conf; + uint32_t key_id_len; + uint8_t key_id[16]; +} wv2_inject_key_in; + +typedef struct { + PAVP_CMD_HEADER Header; +// uint8_t enc_content_key[16]; +} wv2_inject_key_out; + + +/*wv2_process_video_frame*/ +typedef struct { + PAVP_CMD_HEADER Header; + transcript_conf conf; + uint32_t session_id; + uint32_t frame_offset; + uint32_t metadata_offset; + uint32_t header_offset; + uint32_t dest_offset; + uint32_t key_id_len; + uint8_t key_id[16]; +} wv2_process_video_frame_in; + +//typedef PAVP_CMD_NODATA wv2_process_video_frame_out +typedef struct { + PAVP_CMD_HEADER Header; + uint32_t parsed_data_size;; + //uint8_t iv[16]; ////////this is temporary +} wv2_process_video_frame_out; class OMXVideoDecoderAVCSecure : public OMXVideoDecoderBase { public: @@ -117,6 +223,14 @@ private: pavp_lib_session *mpLibInstance; bool mDropUntilIDR; + uint32_t mPAVPAppID; + OMX_ERRORTYPE CreatePavpSession(void); + OMX_ERRORTYPE SecPassThrough(uint8_t*, uint32_t, uint8_t*, uint32_t); + OMX_ERRORTYPE MdrmInjectKey(uint8_t, uint8_t*); + OMX_ERRORTYPE WvSetTranscriptKey(void); + OMX_ERRORTYPE ManagePAVPSession(bool); + OMX_ERRORTYPE ClassicProcessVideoFrame(SECVideoBuffer *secBuffer, uint32_t*); + OMX_ERRORTYPE ModularProcessVideoFrame(SECVideoBuffer *secBuffer, uint32_t*); }; #endif /* OMX_VIDEO_DECODER_AVC_SECURE_H_ */ diff --git a/videocodec/securevideo/baytrail/widevine.h b/videocodec/securevideo/baytrail/widevine.h index a53a822..0bd0224 100644 --- a/videocodec/securevideo/baytrail/widevine.h +++ b/videocodec/securevideo/baytrail/widevine.h @@ -327,8 +327,17 @@ typedef struct { uint8_t device_id[WV_DEVICE_ID_SIZE];
} wv_heci_get_keybox_data_out;
+//orig
+#if 0
/*wv_set_xcript_key*/
typedef PAVP_CMD_NODATA wv_set_xcript_key_in;
+#endif
+
+//for app-ID
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint32_t StreamId;
+} wv_set_xcript_key_in;
typedef struct {
PAVP_CMD_HEADER Header;
|
