diff options
| author | Ryan Saffores <ryan.d.saffores@intel.com> | 2013-12-03 16:35:25 -0800 |
|---|---|---|
| committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 22:02:56 -0700 |
| commit | 7dd377db8d048cae4ddd459f97fd24643d7defe8 (patch) | |
| tree | 44aaab7e062ecbd982497abe82ad3428c8fa72f8 /videocodec/securevideo | |
| parent | b6f41f9d03897dbc6e44887d2e3ad2d7a26ed203 (diff) | |
| download | android_hardware_intel_common_omx-components-7dd377db8d048cae4ddd459f97fd24643d7defe8.tar.gz android_hardware_intel_common_omx-components-7dd377db8d048cae4ddd459f97fd24643d7defe8.tar.bz2 android_hardware_intel_common_omx-components-7dd377db8d048cae4ddd459f97fd24643d7defe8.zip | |
Adding secure video decoder for cherrytrail build target
BZ: 156337
Adding directory with secure video decoder for cherrytrail
Change-Id: I736304a467298e097b5059c94eaf6d00f5939334
Signed-off-by: Ryan Saffores <ryan.d.saffores@intel.com>
Diffstat (limited to 'videocodec/securevideo')
| -rw-r--r-- | videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.cpp | 534 | ||||
| -rw-r--r-- | videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.h | 122 | ||||
| -rw-r--r-- | videocodec/securevideo/cherrytrail/secvideoparser.h | 141 | ||||
| -rw-r--r-- | videocodec/securevideo/cherrytrail/widevine.h | 491 |
4 files changed, 1288 insertions, 0 deletions
diff --git a/videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.cpp b/videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.cpp new file mode 100644 index 0000000..583eed2 --- /dev/null +++ b/videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.cpp @@ -0,0 +1,534 @@ +/* +* Copyright (c) 2009-2013 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoDecoder" +#include <utils/Log.h> +#include "OMXVideoDecoderAVCSecure.h" +#include <time.h> +#include <signal.h> +#include <pthread.h> +#include <stdlib.h> +#include <stdint.h> +#include <byteswap.h> + +#define LOGVAR(v) LOGD("LOGVAR: " #v " = %d", v) + +// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) +static const char* AVC_MIME_TYPE = "video/avc"; +static const char* AVC_SECURE_MIME_TYPE = "video/avc-secure"; + +OMXVideoDecoderAVCSecure::OMXVideoDecoderAVCSecure() + : mpLibInstance(NULL), + mDropUntilIDR(false) { + LOGV("OMXVideoDecoderAVCSecure is constructed."); + mVideoDecoder = createVideoDecoder(AVC_SECURE_MIME_TYPE); + if (!mVideoDecoder) { + LOGE("createVideoDecoder failed for \"%s\"", AVC_SECURE_MIME_TYPE); + } + // Override default native buffer count defined in the base class + mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT; + + memset(mOMXSecureBuffers, 0, sizeof(mOMXSecureBuffers)); + memset(mParsedFrames, 0, sizeof(mParsedFrames)); + + BuildHandlerList(); +} + +OMXVideoDecoderAVCSecure::~OMXVideoDecoderAVCSecure() { + // Cleanup any buffers that weren't freed + for(int i = 0; i < INPORT_ACTUAL_BUFFER_COUNT; i++) { + if(mOMXSecureBuffers[i]) { + delete mOMXSecureBuffers[i]; + } + } + LOGV("OMXVideoDecoderAVCSecure is destructed."); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { + // OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; + paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + + // OMX_VIDEO_PARAM_AVCTYPE + memset(&mParamAvc, 0, sizeof(mParamAvc)); + SetTypeHeader(&mParamAvc, sizeof(mParamAvc)); + mParamAvc.nPortIndex = INPORT_INDEX; + // TODO: check eProfile/eLevel + mParamAvc.eProfile = OMX_VIDEO_AVCProfileHigh; //OMX_VIDEO_AVCProfileBaseline; + mParamAvc.eLevel = OMX_VIDEO_AVCLevel41; //OMX_VIDEO_AVCLevel1; + + // Set memory allocator + this->ports[INPORT_INDEX]->SetMemAllocator(MemAllocSecure, MemFreeSecure, this); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorStop(void) { + // destroy PAVP session + if(mpLibInstance) { + pavp_lib_session::pavp_lib_code rc = pavp_lib_session::status_ok; + LOGI("Destroying the PAVP session...\n"); + rc = mpLibInstance->pavp_destroy_session(); + if (rc != pavp_lib_session::status_ok) + LOGE("pavp_destroy_session failed with error 0x%x\n", rc); + } + return OMXVideoDecoderBase::ProcessorStop(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorProcess( + OMX_BUFFERHEADERTYPE ***pBuffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::ProcessorProcess(pBuffers, retains, numberBuffers); + if (ret != OMX_ErrorNone) { + LOGE("OMXVideoDecoderBase::ProcessorProcess failed. Result: %#x", ret); + return ret; + } + + if (mDropUntilIDR) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; + OMX_BUFFERHEADERTYPE *pOutput = *pBuffers[OUTPORT_INDEX]; + pOutput->nFilledLen = 0; + return OMX_ErrorNone; + } + + return ret; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareConfigBuffer(VideoConfigBuffer *p) { + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::PrepareConfigBuffer(p); + CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareConfigBuffer"); + p->flag |= WANT_SURFACE_PROTECTION; + return ret; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); + CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareDecodeBuffer"); + + 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) { + LOGW("buffer offset %lu is not zero!!!", buffer->nOffset); + } + + OMXSecureBuffer *secureBuffer = (OMXSecureBuffer*)buffer->pBuffer; + if(!secureBuffer) { + LOGE("OMXSecureBuffer is NULL"); + return OMX_ErrorBadParameter; + } + SECVideoBuffer *secBuffer = (SECVideoBuffer*)secureBuffer->secBuffer; + if(!secureBuffer) { + LOGE("SECVideoBuffer is NULL"); + 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; + } + } + } + + 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); + } + + if (balive == false || (ret == OMX_ErrorNotReady)) { + + 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(); + + mpLibInstance = NULL; + mDropUntilIDR = true; + } + } + + 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; + } + } + } + + 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; + } + } + } + + 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; + } + + return ret; +} + +OMX_COLOR_FORMATTYPE OMXVideoDecoderAVCSecure::GetOutputColorFormat(int width, int height) { + // CHT HWC expects Tiled output color format for all resolution + return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::BuildHandlerList(void) { + OMXVideoDecoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc); + AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoAVCProfileLevel, SetParamVideoAVCProfileLevel); + AddHandler(static_cast<OMX_INDEXTYPE> (OMX_IndexExtEnableNativeBuffer), GetNativeBufferMode, SetNativeBufferMode); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::GetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + + memcpy(p, &mParamAvc, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortAvcParam implementation - Can we make simple copy???? + memcpy(&mParamAvc, p, sizeof(mParamAvc)); + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::GetParamVideoAVCProfileLevel(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_ENUMERATION_RANGE(p->nProfileIndex,1); + + p->eProfile = mParamAvc.eProfile; + p->eLevel = mParamAvc.eLevel; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetParamVideoAVCProfileLevel(OMX_PTR pStructure) { + LOGW("SetParamVideoAVCProfileLevel is not supported."); + return OMX_ErrorUnsupportedSetting; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::GetNativeBufferMode(OMX_PTR pStructure) { + LOGE("GetNativeBufferMode is not implemented"); + return OMX_ErrorNotImplemented; +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetNativeBufferMode(OMX_PTR pStructure) { + OMXVideoDecoderBase::SetNativeBufferMode(pStructure); + PortVideo *port = NULL; + port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); + + OMX_PARAM_PORTDEFINITIONTYPE port_def; + memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def)); + port_def.format.video.eColorFormat = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled; + port->SetPortDefinition(&port_def,true); + + return OMX_ErrorNone; +} + +OMX_U8* OMXVideoDecoderAVCSecure::MemAllocSecure(OMX_U32 nSizeBytes, OMX_PTR pUserData) { + OMXVideoDecoderAVCSecure* p = (OMXVideoDecoderAVCSecure *)pUserData; + if (p) { + return p->MemAllocSecure(nSizeBytes); + } + LOGE("NULL pUserData."); + return NULL; +} + +void OMXVideoDecoderAVCSecure::MemFreeSecure(OMX_U8 *pBuffer, OMX_PTR pUserData) { + OMXVideoDecoderAVCSecure* p = (OMXVideoDecoderAVCSecure *)pUserData; + if (p) { + p->MemFreeSecure(pBuffer); + return; + } + LOGE("NULL pUserData."); +} + +OMX_U8* OMXVideoDecoderAVCSecure::MemAllocSecure(OMX_U32 nSizeBytes) { + if (nSizeBytes > INPORT_BUFFER_SIZE) { + LOGE("Invalid size (%lu) of memory to allocate.", nSizeBytes); + return NULL; + } + LOGW_IF(nSizeBytes != INPORT_BUFFER_SIZE, "WARNING: MemAllocSEC asked to allocate buffer of size %lu (expected %d)", nSizeBytes, INPORT_BUFFER_SIZE); + + uint32_t index = 0; + do { + if(mOMXSecureBuffers[index] == NULL) { + break; + } + } while(++index < INPORT_ACTUAL_BUFFER_COUNT); + + if(index >= INPORT_ACTUAL_BUFFER_COUNT) { + LOGE("No free buffers"); + return NULL; + } + + mOMXSecureBuffers[index] = new OMXSecureBuffer; + if(!mOMXSecureBuffers[index]) { + LOGE("Failed to allocate OMXSecureBuffer."); + return NULL; + } + + mOMXSecureBuffers[index]->index = index; + // SEC buffer will by assigned by WVCrypto + mOMXSecureBuffers[index]->secBuffer = NULL; + + return (OMX_U8*)mOMXSecureBuffers[index]; +} + +void OMXVideoDecoderAVCSecure::MemFreeSecure(OMX_U8 *pBuffer) { + OMXSecureBuffer *p = (OMXSecureBuffer*) pBuffer; + if (p == NULL) { + return; + } + + uint32_t index = p->index; + if(mOMXSecureBuffers[index] == p) { + delete(p); + mOMXSecureBuffers[index] = NULL; + } else { + LOGE("ERROR: pBuffer (%p) does not match mOMXSecureBuffer[%d] pointer (%p)", p, index, mOMXSecureBuffers[index]); + } +} + +// Byteswap slice header (SEC returns the slice header with fields in big-endian byte order) +inline void byteswap_slice_header(slice_header_t* slice_header) { + // Byteswap the fields of slice_header + slice_header->first_mb_in_slice = bswap_32(slice_header->first_mb_in_slice); + slice_header->frame_num = bswap_32(slice_header->frame_num); + slice_header->idr_pic_id = bswap_16(slice_header->idr_pic_id); + slice_header->pic_order_cnt_lsb = bswap_16(slice_header->pic_order_cnt_lsb); + slice_header->delta_pic_order_cnt_bottom = bswap_32(slice_header->delta_pic_order_cnt_bottom); + slice_header->delta_pic_order_cnt[0] = bswap_32(slice_header->delta_pic_order_cnt[0]); + slice_header->delta_pic_order_cnt[1] = bswap_32(slice_header->delta_pic_order_cnt[1]); +} + +OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ConstructFrameInfo( + uint8_t* frame_data, + uint32_t frame_size, + pavp_info_t* pavp_info, + uint8_t* nalu_data, + uint32_t nalu_data_size, + frame_info_t* frame_info) { + + uint32_t* dword_ptr = (uint32_t*)nalu_data; + uint8_t* byte_ptr = NULL; + uint32_t data_size = 0; + + frame_info->data = frame_data; + frame_info->length = frame_size; + frame_info->pavp = pavp_info; + frame_info->dec_ref_pic_marking = NULL; + + // Byteswap nalu data (SEC returns fields in big-endian byte order) + frame_info->num_nalus = bswap_32(*dword_ptr); + dword_ptr++; + for(uint32_t n = 0; n < frame_info->num_nalus; n++) { + // Byteswap offset + frame_info->nalus[n].offset = bswap_32(*dword_ptr); + dword_ptr++; + + // Byteswap nalu_size + frame_info->nalus[n].length = bswap_32(*dword_ptr); + dword_ptr++; + + // Byteswap data_size + data_size = bswap_32(*dword_ptr); + dword_ptr++; + + byte_ptr = (uint8_t*)dword_ptr; + frame_info->nalus[n].type = *byte_ptr; + switch(frame_info->nalus[n].type & 0x1F) { + case h264_NAL_UNIT_TYPE_SPS: + case h264_NAL_UNIT_TYPE_PPS: + case h264_NAL_UNIT_TYPE_SEI: + // Point to cleartext in nalu data buffer + frame_info->nalus[n].data = byte_ptr; + frame_info->nalus[n].slice_header = NULL; + break; + case h264_NAL_UNIT_TYPE_SLICE: + case h264_NAL_UNIT_TYPE_IDR: + // Point to ciphertext in frame buffer + frame_info->nalus[n].data = frame_info->data + frame_info->nalus[n].offset; + byteswap_slice_header((slice_header_t*)byte_ptr); + frame_info->nalus[n].slice_header = (slice_header_t*)byte_ptr; + if(data_size > sizeof(slice_header_t)) { + byte_ptr += sizeof(slice_header_t); + frame_info->dec_ref_pic_marking = (dec_ref_pic_marking_t*)byte_ptr; + } + break; + default: + LOGE("ERROR: SEC returned an unsupported NALU type: %x", frame_info->nalus[n].type); + frame_info->nalus[n].data = NULL; + frame_info->nalus[n].slice_header = NULL; + break; + } + + // Advance to next NALU (including padding) + dword_ptr += (data_size + 3) >> 2; + } + + return OMX_ErrorNone; +} + +DECLARE_OMX_COMPONENT("OMX.Intel.hw_vd.h264.secure", "video_decoder.avc", OMXVideoDecoderAVCSecure); diff --git a/videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.h b/videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.h new file mode 100644 index 0000000..77c2748 --- /dev/null +++ b/videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.h @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2009-2013 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OMX_VIDEO_DECODER_AVC_SECURE_H_ +#define OMX_VIDEO_DECODER_AVC_SECURE_H_ + +#include <utils/Mutex.h> +#include "OMXVideoDecoderBase.h" +#include "libpavp.h" +#include "widevine.h" +#include "secvideoparser.h" + +// Must match the same structs defined in WVCrypto.h +#pragma pack(push, 1) +typedef struct { + uint32_t offset; + uint32_t size; +} sec_partition_t; +typedef struct { + sec_partition_t src; + sec_partition_t dest; + sec_partition_t metadata; + sec_partition_t headers; +} video_partition_t; +typedef struct { + pavp_lib_session* pLibInstance; + uint8_t* base; + uint32_t size; + uint32_t base_offset; + video_partition_t partitions; + uint32_t frame_size; + uint32_t src_fill; + uint8_t pes_packet_count; + uint8_t clear; +} SECVideoBuffer; +typedef struct { + uint32_t index; + SECVideoBuffer* secBuffer; +} OMXSecureBuffer; +#pragma pack(pop) + + +class OMXVideoDecoderAVCSecure : public OMXVideoDecoderBase { +public: + OMXVideoDecoderAVCSecure(); + virtual ~OMXVideoDecoderAVCSecure(); + +protected: + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput);; + virtual OMX_ERRORTYPE ProcessorStop(void); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE ***pBuffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE PrepareConfigBuffer(VideoConfigBuffer *p); + virtual OMX_ERRORTYPE PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p); + virtual OMX_COLOR_FORMATTYPE GetOutputColorFormat(int width, int height); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + DECLARE_HANDLER(OMXVideoDecoderAVCSecure, ParamVideoAvc); + DECLARE_HANDLER(OMXVideoDecoderAVCSecure, ParamVideoAVCProfileLevel); + DECLARE_HANDLER(OMXVideoDecoderAVCSecure, NativeBufferMode); + + static OMX_U8* MemAllocSecure(OMX_U32 nSizeBytes, OMX_PTR pUserData); + static void MemFreeSecure(OMX_U8 *pBuffer, OMX_PTR pUserData); + OMX_U8* MemAllocSecure(OMX_U32 nSizeBytes); + void MemFreeSecure(OMX_U8 *pBuffer); + + OMX_ERRORTYPE ConstructFrameInfo(uint8_t* frame_data, uint32_t frame_size, + pavp_info_t* pavp_info, uint8_t* nalu_data, uint32_t nalu_data_size, + frame_info_t* frame_info); + +private: + + enum { + // WARNING: if these values are changed, please make corresponding changes + // in the SEC memory region partitioning in the OEMCrypto for BYT (secregion.h) + + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_BUFFER_SIZE = 1382400, + + // for OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS + // default number of reference frame + NUM_REFERENCE_FRAME = 4, + + OUTPORT_NATIVE_BUFFER_COUNT = 20, + }; + + OMX_VIDEO_PARAM_AVCTYPE mParamAvc; + + OMXSecureBuffer* mOMXSecureBuffers[INPORT_ACTUAL_BUFFER_COUNT]; + + struct SECParsedFrame { + uint8_t* nalu_data; + uint32_t nalu_data_size; + pavp_info_t pavp_info; + frame_info_t frame_info; + }; + + SECParsedFrame mParsedFrames[INPORT_ACTUAL_BUFFER_COUNT]; + + pavp_lib_session *mpLibInstance; + bool mDropUntilIDR; +}; + +#endif /* OMX_VIDEO_DECODER_AVC_SECURE_H_ */ diff --git a/videocodec/securevideo/cherrytrail/secvideoparser.h b/videocodec/securevideo/cherrytrail/secvideoparser.h new file mode 100644 index 0000000..bf10a71 --- /dev/null +++ b/videocodec/securevideo/cherrytrail/secvideoparser.h @@ -0,0 +1,141 @@ +/* INTEL CONFIDENTIAL +* Copyright (c) 2013 Intel Corporation. All rights reserved. +* +* The source code contained or described herein and all documents +* related to the source code ("Material") are owned by Intel +* Corporation or its suppliers or licensors. Title to the +* Material remains with Intel Corporation or its suppliers and +* licensors. The Material contains trade secrets and proprietary +* and confidential information of Intel or its suppliers and +* licensors. The Material is protected by worldwide copyright and +* trade secret laws and treaty provisions. No part of the Material +* may be used, copied, reproduced, modified, published, uploaded, +* posted, transmitted, distributed, or disclosed in any way without +* Intel's prior express written permission. +* +* No license under any patent, copyright, trade secret or other +* intellectual property right is granted to or conferred upon you +* by disclosure or delivery of the Materials, either expressly, by +* implication, inducement, estoppel or otherwise. Any license +* under such intellectual property rights must be express and +* approved by Intel in writing. +*/ + +#ifndef SEC_VIDEO_PARSER_H_ +#define SEC_VIDEO_PARSER_H_ + +#include <stdint.h> + +/* H264 start code values */ +typedef enum _h264_nal_unit_type +{ + h264_NAL_UNIT_TYPE_unspecified = 0, + h264_NAL_UNIT_TYPE_SLICE, + h264_NAL_UNIT_TYPE_DPA, + h264_NAL_UNIT_TYPE_DPB, + h264_NAL_UNIT_TYPE_DPC, + h264_NAL_UNIT_TYPE_IDR, + h264_NAL_UNIT_TYPE_SEI, + h264_NAL_UNIT_TYPE_SPS, + h264_NAL_UNIT_TYPE_PPS, + h264_NAL_UNIT_TYPE_Acc_unit_delimiter, + h264_NAL_UNIT_TYPE_EOSeq, + h264_NAL_UNIT_TYPE_EOstream, + h264_NAL_UNIT_TYPE_filler_data, + h264_NAL_UNIT_TYPE_SPS_extension, + h264_NAL_UNIT_TYPE_ACP = 19, + h264_NAL_UNIT_TYPE_Slice_extension = 20 +} h264_nal_unit_type_t; + +#define MAX_OP 16 + +enum dec_ref_pic_marking_flags { + IDR_PIC_FLAG = 0, + NO_OUTPUT_OF_PRIOR_PICS_FLAG, + LONG_TERM_REFERENCE_FLAG, + ADAPTIVE_REF_PIC_MARKING_MODE_FLAG +}; + +typedef struct _dec_ref_pic_marking_t { + union { + uint8_t flags; + struct { + uint8_t idr_pic_flag:1; + uint8_t no_output_of_prior_pics_flag:1; + uint8_t long_term_reference_flag:1; + uint8_t adaptive_ref_pic_marking_mode_flag:1; + }; + }; + struct { + uint8_t memory_management_control_operation; + union { + struct { + uint8_t difference_of_pic_nums_minus1; + } op1; + struct { + uint8_t long_term_pic_num; + } op2; + struct { + uint8_t difference_of_pic_nums_minus1; + uint8_t long_term_frame_idx; + } op3; + struct { + uint8_t max_long_term_frame_idx_plus1; + } op4; + struct { + uint8_t long_term_frame_idx; + } op6; + }; + } op[MAX_OP]; +} dec_ref_pic_marking_t; + +enum slice_header_flags { + FIELD_PIC_FLAG = 0, + BOTTOM_FIELD_FLAG +}; + +typedef struct _slice_header_t { + uint8_t nal_unit_type; + union { + uint8_t flags; + struct { + uint8_t field_pic_flag:1; + uint8_t bottom_field_flag:1; + }; + }; + uint8_t pps_id; + uint8_t padding; // Align the next field to a 32-bit address + uint32_t first_mb_in_slice; + uint32_t frame_num; + uint16_t idr_pic_id; + uint16_t pic_order_cnt_lsb; + int32_t delta_pic_order_cnt_bottom; + int32_t delta_pic_order_cnt[2]; +} slice_header_t; + +typedef struct { + uint8_t type; + uint32_t offset; + uint8_t* data; + uint32_t length; + slice_header_t* slice_header; +} nalu_info_t; + +typedef struct { + uint32_t iv[4]; + uint32_t mode; + uint32_t app_id; +} pavp_info_t; + +#define MAX_NUM_NALUS 20 + +typedef struct { + uint8_t* data; + uint32_t length; + pavp_info_t* pavp; + dec_ref_pic_marking_t* dec_ref_pic_marking; + uint32_t num_nalus; + nalu_info_t nalus[MAX_NUM_NALUS]; +} frame_info_t; + +#endif /* SEC_VIDEO_PARSER_H_ */ diff --git a/videocodec/securevideo/cherrytrail/widevine.h b/videocodec/securevideo/cherrytrail/widevine.h new file mode 100644 index 0000000..a53a822 --- /dev/null +++ b/videocodec/securevideo/cherrytrail/widevine.h @@ -0,0 +1,491 @@ +/*++
+
+ INTEL CONFIDENTIAL
+ Copyright (c) 2013- Intel Corporation All Rights Reserved.
+
+ The source code contained or described herein and all documents related to
+ the source code ("Material") are owned by Intel Corporation or its
+ suppliers or licensors. Title to the Material remains with Intel
+ Corporation or its suppliers and licensors. The Material contains trade
+ secrets and proprietary and confidential information of Intel or its
+ suppliers and licensors. The Material is protected by worldwide copyright
+ and trade secret laws and treaty provisions. No part of the Material may be
+ used, copied, reproduced, modified, published, uploaded, posted, transmitted,
+ distributed, or disclosed in any way without Intel's prior express written
+ permission.
+
+ No license under any patent, copyright, trade secret or other intellectual
+ property right is granted to or conferred upon you by disclosure or delivery
+ of the Materials, either expressly, by implication, inducement, estoppel or
+ otherwise. Any license under such intellectual property rights must be
+ express and approved by Intel in writing.
+
+File Name:
+
+ widevine.h
+
+Abstract:
+
+
+
+Author:
+
+ Ruan, Xiaoyu
+ Patel, Arpit A
+
+Revision history:
+
+ 3/17/2013: WV SEC FW API v0.19
+ 3/21/2013: v0.30
+ 3/29/2013: v0.40
+ 4/4/2013: v0.43
+ 4/8/2013: v0.45
+ 4/11/2013: v0.50
+ 4/24/2013: v0.51
+
+--*/
+
+#ifndef __WIDEVINE_H
+#define __WIDEVINE_H
+
+#if 0
+#include "CompMgmt.h"
+#include "Heci.h"
+#include "Crypto.h"
+#include "Storage.h"
+#include "Memory.h"
+#include "MemDefs.h"
+#include <string.h>
+
+#include "PavpHeciApiCommonDefs.h"
+#include "PavpHeciApi.h"
+#include "PavpVideoKeyMgr.h"
+#include "PavpBaseKeyMgr.h"
+#include "GfxKeyMgrDefs.h"
+
+#include "dbg.h"
+#include "romapi.h"
+
+#include "bitstream.h"
+#include "decoder.h"
+#include "nalu.h"
+#include "sei.h"
+#include "sps.h"
+#include "pps.h"
+#include "slice_header.h"
+#include "flag.h"
+#endif
+
+#define WV_USE_SATT 1
+
+#define WV_1KB 1024
+#define WV_DEVICE_ID_SIZE 32
+#define WV_DEVICE_KEY_SIZE 16
+#define WV_KEY_DATA_SIZE 72
+#define MV_KEYBOX_MAGIC_SIZE 4
+#define WV_CRC_SIZE 4
+#define WV_MAGIC_SIZE 4
+#define WV_AES_IV_SIZE 16
+#define WV_AES_KEY_SIZE 16
+#define WV_AES_BLOCK_SIZE 16
+#define WV_MAX_PACKETS_IN_FRAME 20 /* 20*64K=1.3M, max frame size */
+#define WV_MAX_PACKET_SIZE (64*WV_1KB-1)
+#define WV_PARSED_BUFFER_SIZE (4*WV_1KB)
+#define WV_PER_DMA_SIZE (8*WV_1KB + 16 + 16) /* 16 is AES block size, for CTS last block. add 16 more for DMA alignment */
+#define WV_PARSER_BUF_EDGE 64
+#define WV_WORK_BUFFER_SIZE (WV_PER_DMA_SIZE+WV_PARSER_BUF_EDGE)
+#define WV_ECM_SIZE 32
+#define WV_FLAGS_SIZE 4
+#define WV_RAND_SIZE 32
+#define WV_API_VERSION 0x00010000
+#define WV_FRAME_METADATA_SIZE (WV_MAX_PACKETS_IN_FRAME*sizeof(wv_frame_metadata))
+#define WV_MALLOC_ALIGNMENT 32
+#define WV_MALLOC_TIMEOUT 0
+#define WV_DMA_ALIGNMENT 32
+#define WV_XCRIPT_DMA_OUT_SWAP (CIPHER_DST_SWAP)
+#define WV_OUT_MSG_FLAG 0x80000000
+#define WV_SATT_BASE SATT_2
+
+#define WV_CEILING(a,b) ((a)%(b)==0?(a):((a)/(b)+1)*(b))
+#define PREPRODUCTION (RomData.gBringupDataPtr->FuseMap.DevModeEnabled || RomData.gBringupDataPtr->FuseMap.JtagEnabled)
+#define WV_SWAP_DWORD(dword) (((dword) & 0x000000ff) << 24 | ((dword) & 0x0000ff00) << 8 | ((dword) & 0x00ff0000) >> 8 | ((dword) & 0xff000000) >> 24)
+#define WV_SWAP_SHORT(sho) (((sho) & (0x00ff)) << 8 | ((sho) & (0xff00)) >> 8)
+
+/**
+ * @brief PAVP HECI message header.
+ */
+typedef struct _PAVP_CMD_HEADER
+{
+ UINT32 ApiVersion;
+ UINT32 CommandId;
+ UINT32 Status;
+ UINT32 BufferLength;
+} PAVP_CMD_HEADER;
+
+typedef struct _PAVP_CMD_NODATA
+{
+ PAVP_CMD_HEADER Header;
+ // no data follows header
+} PAVP_CMD_NODATA;
+
+typedef int BOOL;
+
+typedef struct {
+ uint8_t device_id[WV_DEVICE_ID_SIZE];
+ uint8_t device_key[WV_DEVICE_KEY_SIZE];
+ uint8_t key_data[WV_KEY_DATA_SIZE];
+ uint8_t magic[WV_MAGIC_SIZE];
+ uint8_t key_data_crc[WV_CRC_SIZE];
+} wv_keybox;
+
+typedef struct {
+ uint32_t packet_byte_size; // number of bytes in this PES packet, same for input and output
+ uint8_t packet_iv[WV_AES_IV_SIZE]; // IV used for CBC-CTS decryption, if the PES packet is encrypted
+} sec_wv_packet_metadata;
+
+typedef struct {
+ sec_wv_packet_metadata *metadata_buffer;//WV_MAX_PACKETS_IN_FRAME * sizeof(wv_packet_metadata)
+ uint32_t title_video_size;
+} wv_frame_metadata;
+
+/* wv_nalu and wv_nalu_headers are for host only. FW does not use */
+typedef struct {
+ uint32_t imr_offset;
+ uint32_t nalu_size;
+ uint32_t data_size;
+ uint8_t data[1]; //place holder. actual size is data_size
+} wv_nalu;
+
+/* wv_nalu and wv_nalu_headers are for host only. FW does not use */
+typedef struct {
+ uint32_t num_nalu;
+ wv_nalu drm_nalu[1];// place holder. actual size is num_nalu
+} wv_nalu_headers;
+
+#if 0
+typedef struct {
+ wv_frame_metadata frame_metadata;
+ uint32_t *frame_header; //WV_PARSED_BUFFER_SIZE, dynamic allocation from locked memory
+ uint8_t *frame_proc_buffer;// size = WV_PER_DMA_SIZE, dynamic allocation from locked memory
+ uint8_t *work_buffer;// size = WV_WORK_BUFFER_SIZE, dynamic allocation from locked memory
+ uint8_t *parser_work_buffer;// size = WV_WORK_BUFFER_SIZE, dynamic allocation from locked memory
+ uint8_t asset_key[WV_AES_KEY_SIZE];
+ BOOL asset_key_valid;
+ uint8_t title_key[WV_AES_KEY_SIZE];
+ uint8_t title_decrypt_key[WV_AES_KEY_SIZE];
+ BOOL title_key_valid;
+ uint8_t pavp_key[WV_AES_KEY_SIZE];
+ BOOL pavp_key_valid;
+ uint8_t pavp_counter[WV_AES_IV_SIZE];
+ decoder_ctx_t decoder;
+ uint32_t video_frame_count;
+ BOOL bypass_transcryption;
+ uint32_t audio_frame_count;
+ uint32_t time_start; /*timer starts at first frame of a video frame*/
+ uint32_t time_end; /*timer ends at title_complete*/
+ uint32_t time_start_heci;
+ uint32_t time_heci;
+ uint32_t time_dma_in;
+ uint32_t time_decrypt;
+ uint32_t time_parse;
+ uint32_t time_encrypt_dma_out;
+} wv_title_context;
+
+typedef struct {
+#if !WV_USE_SATT
+ uint32_t host_phy_mem_lo;
+ uint32_t host_phy_mem_hi;
+ uint32_t host_phy_mem_size;
+ BOOL host_phy_mem_valid;
+#endif
+ wv_keybox keybox;
+ BOOL keybox_valid;
+ wv_title_context title;
+ PAVP_STREAM_ID wvVideoStreamSlot;
+} wv_context;
+#endif
+
+/*******************
+ * HECI APIs
+ *******************/
+
+typedef enum {
+ WV_SUCCESS = 0,
+ WV_SUCCESS_PRIV_DATA = 0x80000000,
+ WV_FAIL_INVALID_PARAMS = 0x000F0001,
+ WV_FAIL_INVALID_INPUT_HEADER,
+ WV_FAIL_NOT_PROVISIONED,
+ WV_FAIL_BAD_KEYBOX_CRC,
+ WV_FAIL_UNKNOWN_ERROR,
+ WV_FAIL_HDCP_OFF,
+ WV_FAIL_NO_HOST_MEM,
+ WV_FAIL_NOT_EXPECTED,
+ WV_FAIL_INVALID_AUDIO_FRAME,
+ WV_FAIL_KEYBOX_INVALID_BAD_PROVISIONING,
+ WV_FAIL_KEYBOX_INVALID_BAD_MAGIC,
+ WV_FAIL_WV_NO_ASSET_KEY,
+ WV_FAIL_WV_NO_CEK,
+ WV_FAIL_REACHED_HOST_MEM_LIMIT,
+ WV_FAIL_WV_SESSION_NALU_PARSE_FAILURE,
+ WV_FAIL_WV_SESSION_NALU_PARSE_TOO_MANY_HEADERS,
+ WV_FAIL_GENERATE_RANDOM_NUMBER_FAILURE,
+ WV_FAIL_AES_CBC_FAILURE,
+ WV_FAIL_AES_XCRIPT_FAILURE,
+ WV_FAIL_AES_ECB_FAILURE,
+ WV_FAIL_BLOB_ERROR,
+ WV_FAIL_BAD_AUDIO_CLEAR_PKT,
+ WV_FAIL_NO_TITLE_KEY,
+ WV_FAIL_OUT_OF_MEMORY,
+ WV_FAIL_PAVP_INJECT_KEY_ERROR,
+ WV_FAIL_MSG_NOT_FROM_RING_0,
+ WV_FAIL_DMA_READ,
+ WV_FAIL_DMA_WRITE,
+ WV_FAIL_DMA_WRITE_HEADER,
+ WV_FAIL_INVALID_TITLE_KEY,
+ WV_FAIL_INVALID_PAVP_KEY,
+ WV_FAIL_INVALID_NUM_OF_PACKETS,
+ WV_FAIL_PAVP_INIT_NOT_COMPLETE,
+ WV_FAIL_STATUS_CHAIN_NOT_INITIALIZED,
+ WV_FAIL_OUTPUT_HOST_MEM_OVERLAP,
+ WV_FAIL_NOT_SUPPORTED
+} wv_heci_status;
+
+typedef enum {
+ wv_init_dma = 0x000A0002,
+ wv_heci_begin = wv_init_dma,
+ wv_get_random,
+ wv_get_keybox_data,
+ wv_set_xcript_key,
+ wv_set_entitlement_key,
+ wv_derive_control_word,
+ wv_process_video_frame,
+ wv_process_audio_frame,
+ wv_title_completed,
+ wv_uninit_dma,
+ wv_heci_end = wv_uninit_dma,
+ wv_dbg_get_title_key = 0x000A00F0,
+ wv_heci_dbg_begin = wv_dbg_get_title_key,
+ wv_dbg_get_xcript_key,
+ wv_dbg_dis_xcript_enc,
+ wv_dbg_en_xcript_enc,
+ wv_dbg_get_diag,
+ wv_dbg_set_keybox,
+ wv_dbg_reset_keybox,
+ wv_dbg_set_xcript_key_wo_pavp,
+ wv_dbg_reset_xcript_key_wo_pavp,
+ wv_heci_dbg_end = wv_dbg_reset_xcript_key_wo_pavp,
+
+ wv_init_dma_rsp = (WV_OUT_MSG_FLAG | wv_init_dma),
+ wv_get_random_rsp,
+ wv_get_keybox_data_rsp,
+ wv_set_xcript_key_rsp,
+ wv_set_entitlement_key_rsp,
+ wv_derive_control_word_rsp,
+ wv_process_video_frame_rsp,
+ wv_process_audio_frame_rsp,
+ wv_title_completed_rsp,
+ wv_uninit_dma_rsp,
+ wv_dbg_get_title_key_rsp = (WV_OUT_MSG_FLAG | wv_dbg_get_title_key),
+ wv_dbg_get_xcript_key_rsp,
+ wv_dbg_dis_xcript_enc_rsp,
+ wv_dbg_en_xcript_enc_rsp,
+ wv_dbg_get_diag_rsp,
+ wv_dbg_set_keybox_rsp,
+ wv_dbg_reset_keybox_rsp,
+ wv_dbg_set_xcript_key_wo_pavp_rsp,
+ wv_dbg_reset_xcript_key_wo_pavp_rsp,
+} wv_heci_command_id;
+
+
+/*wv_init_dma*/
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint32_t phy_mem_lo;
+ uint32_t phy_mem_hi;
+ uint32_t phy_mem_size;
+} wv_init_dma_in;
+
+typedef PAVP_CMD_NODATA wv_init_dma_out;
+
+/*wv_heci_get_random*/
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint32_t size_in_bytes;
+} wv_heci_get_random_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint8_t random_bytes[WV_RAND_SIZE];
+} wv_heci_get_random_out;
+
+/*wv_heci_get_keybox_data*/
+typedef PAVP_CMD_NODATA wv_heci_get_keybox_data_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint8_t key_data[WV_KEY_DATA_SIZE];
+ uint8_t device_id[WV_DEVICE_ID_SIZE];
+} wv_heci_get_keybox_data_out;
+
+/*wv_set_xcript_key*/
+typedef PAVP_CMD_NODATA wv_set_xcript_key_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ /* private data for driver. Size excluded in Header.Length
+ * app caller: do not include this field*/
+ //uint8_t wrapped_xcript_key[WV_AES_KEY_SIZE];// libpcp will take care of this. Remove this from OMX.
+} wv_set_xcript_key_out;
+
+/*wv_heci_set_entitlement_key*/
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint8_t entitlement_key[WV_AES_KEY_SIZE];
+} wv_heci_set_entitlement_key_in;
+
+typedef PAVP_CMD_NODATA wv_heci_set_entitlement_key_out;
+
+/*wv_heci_derive_control_word*/
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint8_t ecm[WV_ECM_SIZE];
+} wv_heci_derive_control_word_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint8_t flags[WV_FLAGS_SIZE];
+} wv_heci_derive_control_word_out;
+
+/*wv_heci_process_video_frame*/
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint32_t num_of_packets;//<=20
+ BOOL is_frame_not_encrypted;
+ uint32_t src_offset;
+ uint32_t dest_offset;
+ uint32_t metadata_offset;
+ uint32_t header_offset;
+} wv_heci_process_video_frame_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint32_t parsed_data_size;
+ /* private data for driver. Size excluded in Header.Length
+ * app caller: do not include this field*/ //Remove comment
+ uint8_t iv[WV_AES_IV_SIZE];
+} wv_heci_process_video_frame_out;
+
+/*wv_heci_process_audio_frame*/
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint32_t num_of_packets;//<=20
+ BOOL is_frame_not_encrypted;
+ uint32_t src_offset;
+ uint32_t dest_offset;
+ uint32_t metadata_offset;
+} wv_heci_process_audio_frame_in;
+
+typedef PAVP_CMD_NODATA wv_heci_process_audio_frame_out;
+
+/*wv_title_completed*/
+typedef PAVP_CMD_NODATA wv_title_completed_in;
+typedef PAVP_CMD_NODATA wv_title_completed_out;
+
+/*wv_dbg_get_title_key*/
+typedef PAVP_CMD_NODATA wv_dbg_get_title_key_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ BOOL title_key_valid;
+ uint8_t title_key[WV_AES_KEY_SIZE];
+} wv_dbg_get_title_key_out;
+
+/*wv_uninit_dma*/
+typedef PAVP_CMD_NODATA wv_uninit_dma_in;
+typedef PAVP_CMD_NODATA wv_uninit_dma_out;
+
+/*wv_dbg_get_xcript_key*/
+typedef PAVP_CMD_NODATA wv_dbg_get_xcript_key_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ BOOL xcript_key_valid;
+ uint8_t xcript_key[WV_AES_KEY_SIZE];
+ uint8_t xcript_counter[WV_AES_IV_SIZE];
+} wv_dbg_get_xcript_key_out;
+
+/*wv_dbg_dis_xcript_enc*/
+typedef PAVP_CMD_NODATA wv_dbg_dis_xcript_enc_in;
+typedef PAVP_CMD_NODATA wv_dbg_dis_xcript_enc_out;
+
+/*wv_dbg_en_xcript_enc*/
+typedef PAVP_CMD_NODATA wv_dbg_en_xcript_enc_in;
+typedef PAVP_CMD_NODATA wv_dbg_en_xcript_enc_out;
+
+/*wv_dbg_get_diag*/
+typedef PAVP_CMD_NODATA wv_dbg_get_diag_in;
+
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ uint16_t fw_major_ver;
+ uint16_t fw_minor_ver;
+ uint16_t fw_hotfix;
+ uint16_t fw_build;
+ BOOL production_part;
+#if !WV_USE_SATT
+ uint32_t host_phy_mem_lo;
+ uint32_t host_phy_mem_hi;
+ uint32_t host_phy_mem_size;
+ BOOL host_phy_mem_valid;
+#endif
+ uint32_t video_frame_count;
+ uint32_t audio_frame_count;
+ uint32_t slice_count_for_this_frame;
+ uint32_t total_slice_count_for_this_title;
+ uint32_t bypass_transcryption : 1;
+ uint32_t frame_header_valid : 1;
+ uint32_t frame_proc_buffer_valid : 1;
+ uint32_t work_buffer_valid : 1;
+ uint32_t parser_work_buffer_valid : 1;
+ uint32_t asset_key_valid_valid : 1;
+ uint32_t title_key_valid_valid : 1;
+ uint32_t pavp_key_valid : 1;
+ uint32_t keybox_valid : 1;
+ uint32_t reserved1 : 7;
+ uint32_t wvVideoStreamSlot : 8;
+ uint32_t reserved2 : 8;
+ uint32_t time_start; /*timer starts at first frame of a video frame*/
+ uint32_t time_end; /*timer ends at title_complete*/
+ uint32_t time_elapsed; /*time_end - time_start, unit is microsecond*/
+ uint32_t video_size;
+ uint32_t throughput; /*bits/microsecond*/
+ uint32_t time_heci;
+ uint32_t time_dma_in;
+ uint32_t time_decrypt;
+ uint32_t time_parse;
+ uint32_t time_encrypt_dma_out;
+} wv_dbg_get_diag_out;
+//C_ASSERT(sizeof(wv_dbg_get_diag_out) == WV_USE_SATT ? 64 : 48);
+
+/*wv_dbg_set_keybox*/
+typedef struct {
+ PAVP_CMD_HEADER Header;
+ wv_keybox keybox;
+} wv_dbg_set_keybox_in;
+
+typedef PAVP_CMD_NODATA wv_dbg_set_keybox_out;
+
+/*wv_dbg_reset_keybox*/
+typedef PAVP_CMD_NODATA wv_dbg_reset_keybox_in;
+typedef PAVP_CMD_NODATA wv_dbg_reset_keybox_out;
+
+/*wv_dbg_set_xcript_key_wo_pavp*/
+typedef PAVP_CMD_NODATA wv_dbg_set_xcript_key_wo_pavp_in;
+typedef PAVP_CMD_NODATA wv_dbg_set_xcript_key_wo_pavp_out;
+
+/*wv_dbg_reset_xcript_key_wo_pavp*/
+typedef PAVP_CMD_NODATA wv_dbg_reset_xcript_key_wo_pavp_in;
+typedef PAVP_CMD_NODATA wv_dbg_reset_xcript_key_wo_pavp_out;
+
+#endif
+
|
