aboutsummaryrefslogtreecommitdiffstats
path: root/videocodec/securevideo
diff options
context:
space:
mode:
authorRyan Saffores <ryan.d.saffores@intel.com>2013-12-03 16:35:25 -0800
committerPatrick Tjin <pattjin@google.com>2014-07-21 22:02:56 -0700
commit7dd377db8d048cae4ddd459f97fd24643d7defe8 (patch)
tree44aaab7e062ecbd982497abe82ad3428c8fa72f8 /videocodec/securevideo
parentb6f41f9d03897dbc6e44887d2e3ad2d7a26ed203 (diff)
downloadandroid_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.cpp534
-rw-r--r--videocodec/securevideo/cherrytrail/OMXVideoDecoderAVCSecure.h122
-rw-r--r--videocodec/securevideo/cherrytrail/secvideoparser.h141
-rw-r--r--videocodec/securevideo/cherrytrail/widevine.h491
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
+