OMXVideoDecoderAVCSecure.cpp revision 26a110c2a29667599733db5173a751e670b366a5
1/* 2* Copyright (c) 2009-2012 Intel Corporation. All rights reserved. 3* 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15*/ 16 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "OMXVideoDecoder" 20#include <wrs_omxil_core/log.h> 21#include "OMXVideoDecoderAVCSecure.h" 22#include <time.h> 23#include <signal.h> 24#include <pthread.h> 25 26 27extern "C" { 28#include <sepdrm.h> 29#include <pr_drm_api.h> 30#include <fcntl.h> 31#include <linux/psb_drm.h> 32#include "xf86drm.h" 33#include "xf86drmMode.h" 34} 35 36#include "VideoFrameInfo.h" 37 38// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) 39static const char* AVC_MIME_TYPE = "video/avc"; 40static const char* AVC_SECURE_MIME_TYPE = "video/avc-secure"; 41 42#define DATA_BUFFER_INITIAL_OFFSET 0 //1024 43#define DATA_BUFFER_SIZE (8 * 1024 * 1024) 44#define KEEP_ALIVE_INTERVAL 5 // seconds 45#define DRM_KEEP_ALIVE_TIMER 1000000 46#define WV_SESSION_ID 0x00000011 47#define NALU_BUFFER_SIZE 8192 48#define NALU_HEADER_LENGTH 1024 // THis should be changed to 4K 49#define FLUSH_WAIT_INTERVAL (30 * 1000) //30 ms 50 51#define DRM_SCHEME_NONE 0 52#define DRM_SCHEME_WV_CLASSIC 1 53#define DRM_SCHEME_WV_MODULAR 2 54#define DRM_SCHEME_PLAYREADY 3 55 56//#pragma pack(push, 1) 57struct DataBuffer { 58 uint32_t size; 59 uint8_t *data; 60 uint8_t clear; 61 uint32_t drmScheme; 62 uint32_t session_id; //used by PlayReady only 63 uint32_t flags; //used by PlayReady only 64}; 65//#pragma pack(pop) 66 67OMXVideoDecoderAVCSecure::OMXVideoDecoderAVCSecure() 68 : mKeepAliveTimer(0), 69 mSessionPaused(false){ 70 LOGV("OMXVideoDecoderAVCSecure is constructed."); 71 mVideoDecoder = createVideoDecoder(AVC_SECURE_MIME_TYPE); 72 if (!mVideoDecoder) { 73 LOGE("createVideoDecoder failed for \"%s\"", AVC_SECURE_MIME_TYPE); 74 } 75 // Override default native buffer count defined in the base class 76 mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT; 77 78 BuildHandlerList(); 79} 80 81OMXVideoDecoderAVCSecure::~OMXVideoDecoderAVCSecure() { 82 LOGI("OMXVideoDecoderAVCSecure is destructed."); 83 84} 85 86OMX_ERRORTYPE OMXVideoDecoderAVCSecure::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { 87 // OMX_PARAM_PORTDEFINITIONTYPE 88 paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; 89 paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; 90 paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; 91 paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; 92 paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; 93 94 // OMX_VIDEO_PARAM_AVCTYPE 95 memset(&mParamAvc, 0, sizeof(mParamAvc)); 96 SetTypeHeader(&mParamAvc, sizeof(mParamAvc)); 97 mParamAvc.nPortIndex = INPORT_INDEX; 98 // TODO: check eProfile/eLevel 99 mParamAvc.eProfile = OMX_VIDEO_AVCProfileHigh; //OMX_VIDEO_AVCProfileBaseline; 100 mParamAvc.eLevel = OMX_VIDEO_AVCLevel41; //OMX_VIDEO_AVCLevel1; 101 102 this->ports[INPORT_INDEX]->SetMemAllocator(MemAllocDataBuffer, MemFreeDataBuffer, this); 103 104 for (int i = 0; i < INPORT_ACTUAL_BUFFER_COUNT; i++) { 105 mDataBufferSlot[i].offset = DATA_BUFFER_INITIAL_OFFSET + i * INPORT_BUFFER_SIZE; 106 mDataBufferSlot[i].owner = NULL; 107 } 108 109 return OMX_ErrorNone; 110} 111 112OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorInit(void) { 113 mSessionPaused = false; 114 return OMXVideoDecoderBase::ProcessorInit(); 115} 116 117OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorDeinit(void) { 118 // Session should be torn down in ProcessorStop, delayed to ProcessorDeinit 119 // to allow remaining frames completely rendered. 120 LOGI("Calling Drm_DestroySession."); 121 if (mDrmScheme == DRM_SCHEME_WV_CLASSIC) { 122 uint32_t sepres = drm_destroy_session(WV_SESSION_ID); 123 if (sepres != 0) { 124 LOGW("Drm_DestroySession returns %#x", sepres); 125 } 126 } 127 else if(mDrmScheme == DRM_SCHEME_WV_MODULAR) { 128 uint32_t ret = drm_wv_mod_stop_playback(WV_SESSION_ID); 129 if (ret != DRM_WV_MOD_SUCCESS) { 130 LOGW("Modular WV - drm_wv_mod_stop_playback returns %#x", ret); 131 } 132 } 133 return OMXVideoDecoderBase::ProcessorDeinit(); 134} 135 136OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorStart(void) { 137 uint32_t imrOffset = 0; 138 uint32_t dataBufferSize = DATA_BUFFER_SIZE; 139 140 mSessionPaused = false; 141 return OMXVideoDecoderBase::ProcessorStart(); 142} 143 144OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorStop(void) { 145 if (mKeepAliveTimer != 0) { 146 timer_delete(mKeepAliveTimer); 147 mKeepAliveTimer = 0; 148 } 149 150 return OMXVideoDecoderBase::ProcessorStop(); 151} 152 153 154OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorFlush(OMX_U32 portIndex) { 155 return OMXVideoDecoderBase::ProcessorFlush(portIndex); 156} 157 158OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorProcess( 159 OMX_BUFFERHEADERTYPE ***pBuffers, 160 buffer_retain_t *retains, 161 OMX_U32 numberBuffers) { 162 163 int ret_value; 164 165 OMX_BUFFERHEADERTYPE *pInput = *pBuffers[INPORT_INDEX]; 166 DataBuffer *dataBuffer = (DataBuffer *)pInput->pBuffer; 167 168 if((dataBuffer->drmScheme == DRM_SCHEME_WV_CLASSIC) && (!mKeepAliveTimer)){ 169 struct sigevent sev; 170 memset(&sev, 0, sizeof(sev)); 171 sev.sigev_notify = SIGEV_THREAD; 172 sev.sigev_value.sival_ptr = this; 173 sev.sigev_notify_function = KeepAliveTimerCallback; 174 175 ret_value = timer_create(CLOCK_REALTIME, &sev, &mKeepAliveTimer); 176 if (ret_value != 0) { 177 LOGE("Failed to create timer."); 178 } else { 179 struct itimerspec its; 180 its.it_value.tv_sec = -1; // never expire 181 its.it_value.tv_nsec = 0; 182 its.it_interval.tv_sec = KEEP_ALIVE_INTERVAL; 183 its.it_interval.tv_nsec = 0; 184 185 ret_value = timer_settime(mKeepAliveTimer, TIMER_ABSTIME, &its, NULL); 186 if (ret_value != 0) { 187 LOGE("Failed to set timer."); 188 } 189 } 190 } 191 192 if (dataBuffer->size == 0) { 193 // error occurs during decryption. 194 LOGW("size of returned data buffer is 0, decryption fails."); 195 mVideoDecoder->flush(); 196 usleep(FLUSH_WAIT_INTERVAL); 197 OMX_BUFFERHEADERTYPE *pOutput = *pBuffers[OUTPORT_INDEX]; 198 pOutput->nFilledLen = 0; 199 // reset Data buffer size 200 dataBuffer->size = INPORT_BUFFER_SIZE; 201 this->ports[INPORT_INDEX]->FlushPort(); 202 this->ports[OUTPORT_INDEX]->FlushPort(); 203 return OMX_ErrorNone; 204 } 205 206 OMX_ERRORTYPE ret; 207 ret = OMXVideoDecoderBase::ProcessorProcess(pBuffers, retains, numberBuffers); 208 if (ret != OMX_ErrorNone) { 209 LOGE("OMXVideoDecoderBase::ProcessorProcess failed. Result: %#x", ret); 210 return ret; 211 } 212 213 if (mSessionPaused && (retains[OUTPORT_INDEX] == BUFFER_RETAIN_GETAGAIN)) { 214 retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; 215 OMX_BUFFERHEADERTYPE *pOutput = *pBuffers[OUTPORT_INDEX]; 216 pOutput->nFilledLen = 0; 217 this->ports[INPORT_INDEX]->FlushPort(); 218 this->ports[OUTPORT_INDEX]->FlushPort(); 219 } 220 221 return ret; 222} 223 224OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorPause(void) { 225 return OMXVideoDecoderBase::ProcessorPause(); 226} 227 228OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorResume(void) { 229 return OMXVideoDecoderBase::ProcessorResume(); 230} 231 232OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareConfigBuffer(VideoConfigBuffer *p) { 233 OMX_ERRORTYPE ret; 234 ret = OMXVideoDecoderBase::PrepareConfigBuffer(p); 235 CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareConfigBuffer"); 236 p->flag |= WANT_SURFACE_PROTECTION; 237 return ret; 238} 239 240OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareClassicWVDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p){ 241 242 OMX_ERRORTYPE ret = OMX_ErrorNone; 243 244 245 p->flag |= HAS_COMPLETE_FRAME; 246 247 if (buffer->nOffset != 0) { 248 LOGW("buffer offset %lu is not zero!!!", buffer->nOffset); 249 } 250 251 DataBuffer *dataBuffer = (DataBuffer *)buffer->pBuffer; 252 if (dataBuffer->clear) { 253 p->data = dataBuffer->data + buffer->nOffset; 254 p->size = buffer->nFilledLen; 255 } else { 256 dataBuffer->size = NALU_BUFFER_SIZE; 257 struct drm_wv_nalu_headers nalu_headers; 258 nalu_headers.p_enc_ciphertext = dataBuffer->data; 259 260 // TODO: NALU Buffer is supposed to be 4k but using 1k, fix it once chaabi fix is there 261 262 nalu_headers.hdrs_buf_len = NALU_HEADER_LENGTH; 263 nalu_headers.frame_size = buffer->nFilledLen; 264 // Make sure that NALU header frame size is 16 bytes aligned 265 nalu_headers.frame_size = (nalu_headers.frame_size + 0xF) & (~0xF); 266 // Use same video buffer to fill NALU headers returned by chaabi, 267 // Adding 4 because the first 4 bytes after databuffer will be used to store length of NALU headers 268 if((nalu_headers.frame_size + NALU_HEADER_LENGTH) > INPORT_BUFFER_SIZE){ 269 LOGE("Not enough buffer for NALU headers"); 270 return OMX_ErrorOverflow; 271 } 272 273 nalu_headers.p_hdrs_buf = (uint8_t *)(dataBuffer->data + nalu_headers.frame_size + 4); 274 nalu_headers.parse_size = buffer->nFilledLen; 275 276 uint32_t res = drm_wv_return_naluheaders(WV_SESSION_ID, &nalu_headers); 277 if (res == DRM_FAIL_FW_SESSION) { 278 LOGW("Drm_WV_ReturnNALUHeaders failed. Session is disabled."); 279 mSessionPaused = true; 280 ret = OMX_ErrorNotReady; 281 } else if (res != 0) { 282 mSessionPaused = false; 283 LOGE("Drm_WV_ReturnNALUHeaders failed. Error = %#x, frame_size: %d, len = %lu", res, nalu_headers.frame_size, buffer->nFilledLen); 284 ret = OMX_ErrorHardware; 285 } else { 286 mSessionPaused = false; 287 288 // If chaabi returns 0 NALU headers fill the frame size to zero. 289 if (!nalu_headers.hdrs_buf_len) { 290 p->size = 0; 291 return ret; 292 } 293 else{ 294 // NALU headers are appended to encrypted video bitstream 295 // |...encrypted video bitstream (16 bytes aligned)...| 4 bytes of header size |...NALU headers..| 296 uint32_t *ptr = (uint32_t*)(dataBuffer->data + nalu_headers.frame_size); 297 *ptr = nalu_headers.hdrs_buf_len; 298 p->data = dataBuffer->data; 299 p->size = nalu_headers.frame_size; 300 p->flag |= IS_SECURE_DATA; 301 } 302 } 303 } 304 305 // reset Data size 306 dataBuffer->size = NALU_BUFFER_SIZE; 307 return ret; 308} 309OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareModularWVDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p){ 310 OMX_ERRORTYPE ret = OMX_ErrorNone; 311 312 // OMX_BUFFERFLAG_CODECCONFIG is an optional flag 313 // if flag is set, buffer will only contain codec data. 314 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 315 LOGI("Received AVC codec data."); 316 // return ret; 317 } 318 p->flag |= HAS_COMPLETE_FRAME | IS_SUBSAMPLE_ENCRYPTION; 319 320 if (buffer->nOffset != 0) { 321 LOGW("buffer offset %lu is not zero!!!", buffer->nOffset); 322 } 323 324 DataBuffer *dataBuffer = (DataBuffer *)buffer->pBuffer; 325 p->data = dataBuffer->data; 326 p->size = sizeof(frame_info_t); 327 p->flag |= IS_SECURE_DATA; 328 return ret; 329} 330 331 332OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PreparePlayReadyDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p){ 333 OMX_ERRORTYPE ret = OMX_ErrorNone; 334 335 // OMX_BUFFERFLAG_CODECCONFIG is an optional flag 336 // if flag is set, buffer will only contain codec data. 337 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 338 LOGV("PR: Received codec data."); 339 return ret; 340 } 341 p->flag |= HAS_COMPLETE_FRAME; 342 343 if (buffer->nOffset != 0) { 344 LOGW("PR:buffer offset %lu is not zero!!!", buffer->nOffset); 345 } 346 347 DataBuffer *dataBuffer = (DataBuffer *)buffer->pBuffer; 348 if (dataBuffer->clear) { 349 p->data = dataBuffer->data + buffer->nOffset; 350 p->size = buffer->nFilledLen; 351 } else { 352 dataBuffer->size = NALU_BUFFER_SIZE; 353 struct drm_nalu_headers nalu_headers; 354 nalu_headers.p_enc_ciphertext = dataBuffer->data; 355 356 // TODO: NALU Buffer is supposed to be 4k but using 1k, fix it once chaabi fix is there 357 nalu_headers.hdrs_buf_len = NALU_HEADER_LENGTH; 358 nalu_headers.frame_size = buffer->nFilledLen; 359 // Make sure that NALU header frame size is 16 bytes aligned 360 nalu_headers.frame_size = (nalu_headers.frame_size + 0xF) & (~0xF); 361 // Use same video buffer to fill NALU headers returned by chaabi, 362 // Adding 4 because the first 4 bytes after databuffer will be used to store length of NALU headers 363 if((nalu_headers.frame_size + NALU_HEADER_LENGTH) > INPORT_BUFFER_SIZE){ 364 LOGE("Not enough buffer for NALU headers"); 365 return OMX_ErrorOverflow; 366 } 367 368 nalu_headers.p_hdrs_buf = (uint8_t *)(dataBuffer->data + nalu_headers.frame_size + 4); 369 nalu_headers.parse_size = buffer->nFilledLen; 370 371 uint32_t res = drm_pr_return_naluheaders(dataBuffer->session_id, &nalu_headers); 372 373 if (res == DRM_FAIL_FW_SESSION || !nalu_headers.hdrs_buf_len) { 374 LOGW("drm_ReturnNALUHeaders failed. Session is disabled."); 375 mSessionPaused = true; 376 ret = OMX_ErrorNotReady; 377 } else if (res != 0) { 378 mSessionPaused = false; 379 LOGE("drm_pr_return_naluheaders failed. Error = %#x, frame_size: %d, len = %lu", res, nalu_headers.frame_size, buffer->nFilledLen); 380 ret = OMX_ErrorHardware; 381 } else { 382 mSessionPaused = false; 383 384 // If chaabi returns 0 NALU headers fill the frame size to zero. 385 if (!nalu_headers.hdrs_buf_len) { 386 p->size = 0; 387 return ret; 388 } 389 else{ 390 // NALU headers are appended to encrypted video bitstream 391 // |...encrypted video bitstream (16 bytes aligned)...| 4 bytes of header size |...NALU headers..| 392 uint32_t *ptr = (uint32_t*)(dataBuffer->data + nalu_headers.frame_size); 393 *ptr = nalu_headers.hdrs_buf_len; 394 p->data = dataBuffer->data; 395 p->size = nalu_headers.frame_size; 396 p->flag |= IS_SECURE_DATA; 397 } 398 } 399 } 400 401 // reset Data size 402 dataBuffer->size = NALU_BUFFER_SIZE; 403 return ret; 404} 405 406OMX_ERRORTYPE OMXVideoDecoderAVCSecure::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { 407 OMX_ERRORTYPE ret; 408 409 ret = OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); 410 CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareDecodeBuffer"); 411 412 if (buffer->nFilledLen == 0) { 413 return OMX_ErrorNone; 414 } 415 416 DataBuffer *dataBuffer = (DataBuffer *)buffer->pBuffer; 417 if(dataBuffer->drmScheme == DRM_SCHEME_WV_CLASSIC){ 418 419 // OMX_BUFFERFLAG_CODECCONFIG is an optional flag 420 // if flag is set, buffer will only contain codec data. 421 mDrmScheme = DRM_SCHEME_WV_CLASSIC; 422 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 423 LOGV("Received AVC codec data."); 424 return ret; 425 } 426 return PrepareClassicWVDecodeBuffer(buffer, retain, p); 427 } 428 else if(dataBuffer->drmScheme == DRM_SCHEME_WV_MODULAR) { 429 mDrmScheme = DRM_SCHEME_WV_MODULAR; 430 return PrepareModularWVDecodeBuffer(buffer, retain, p); 431 } 432 else if(dataBuffer->drmScheme == DRM_SCHEME_PLAYREADY) 433 { 434 mDrmScheme = DRM_SCHEME_PLAYREADY; 435 return PreparePlayReadyDecodeBuffer(buffer, retain, p); 436 } 437 return ret; 438} 439 440OMX_ERRORTYPE OMXVideoDecoderAVCSecure::BuildHandlerList(void) { 441 OMXVideoDecoderBase::BuildHandlerList(); 442 AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc); 443 AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoAVCProfileLevel, SetParamVideoAVCProfileLevel); 444 return OMX_ErrorNone; 445} 446 447OMX_ERRORTYPE OMXVideoDecoderAVCSecure::GetParamVideoAvc(OMX_PTR pStructure) { 448 OMX_ERRORTYPE ret; 449 OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; 450 CHECK_TYPE_HEADER(p); 451 CHECK_PORT_INDEX(p, INPORT_INDEX); 452 453 memcpy(p, &mParamAvc, sizeof(*p)); 454 return OMX_ErrorNone; 455} 456 457OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetParamVideoAvc(OMX_PTR pStructure) { 458 OMX_ERRORTYPE ret; 459 OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; 460 CHECK_TYPE_HEADER(p); 461 CHECK_PORT_INDEX(p, INPORT_INDEX); 462 CHECK_SET_PARAM_STATE(); 463 464 // TODO: do we need to check if port is enabled? 465 // TODO: see SetPortAvcParam implementation - Can we make simple copy???? 466 memcpy(&mParamAvc, p, sizeof(mParamAvc)); 467 return OMX_ErrorNone; 468} 469 470 471OMX_ERRORTYPE OMXVideoDecoderAVCSecure::GetParamVideoAVCProfileLevel(OMX_PTR pStructure) { 472 OMX_ERRORTYPE ret; 473 OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure; 474 CHECK_TYPE_HEADER(p); 475 CHECK_PORT_INDEX(p, INPORT_INDEX); 476 CHECK_ENUMERATION_RANGE(p->nProfileIndex,1); 477 478 p->eProfile = mParamAvc.eProfile; 479 p->eLevel = mParamAvc.eLevel; 480 481 return OMX_ErrorNone; 482} 483 484OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetParamVideoAVCProfileLevel(OMX_PTR pStructure) { 485 LOGW("SetParamVideoAVCProfileLevel is not supported."); 486 return OMX_ErrorUnsupportedSetting; 487} 488 489OMX_U8* OMXVideoDecoderAVCSecure::MemAllocDataBuffer(OMX_U32 nSizeBytes, OMX_PTR pUserData) { 490 OMXVideoDecoderAVCSecure* p = (OMXVideoDecoderAVCSecure *)pUserData; 491 if (p) { 492 return p->MemAllocDataBuffer(nSizeBytes); 493 } 494 LOGE("NULL pUserData."); 495 return NULL; 496} 497 498void OMXVideoDecoderAVCSecure::MemFreeDataBuffer(OMX_U8 *pBuffer, OMX_PTR pUserData) { 499 OMXVideoDecoderAVCSecure* p = (OMXVideoDecoderAVCSecure *)pUserData; 500 if (p) { 501 p->MemFreeDataBuffer(pBuffer); 502 return; 503 } 504 LOGE("NULL pUserData."); 505} 506 507OMX_U8* OMXVideoDecoderAVCSecure::MemAllocDataBuffer(OMX_U32 nSizeBytes) { 508 if (nSizeBytes > INPORT_BUFFER_SIZE) { 509 LOGE("Invalid size (%lu) of memory to allocate.", nSizeBytes); 510 return NULL; 511 } 512 LOGW_IF(nSizeBytes != INPORT_BUFFER_SIZE, "Size of memory to allocate is %lu", nSizeBytes); 513 for (int i = 0; i < INPORT_ACTUAL_BUFFER_COUNT; i++) { 514 if (mDataBufferSlot[i].owner == NULL) { 515 DataBuffer *pBuffer = new DataBuffer; 516 if (pBuffer == NULL) { 517 LOGE("Failed to allocate memory."); 518 return NULL; 519 } 520 521 pBuffer->data = new uint8_t [INPORT_BUFFER_SIZE]; 522 if (pBuffer->data == NULL) { 523 delete pBuffer; 524 LOGE("Failed to allocate memory, size to allocate %d.", INPORT_BUFFER_SIZE); 525 return NULL; 526 } 527 528 // Is this required for classic or not? 529 // pBuffer->offset = mDataBufferSlot[i].offset; 530 pBuffer->size = INPORT_BUFFER_SIZE; 531 mDataBufferSlot[i].owner = (OMX_U8 *)pBuffer; 532 533 LOGV("Allocating buffer = %#x, Data offset = %#x, data = %#x", (uint32_t)pBuffer, mDataBufferSlot[i].offset, (uint32_t)pBuffer->data); 534 return (OMX_U8 *) pBuffer; 535 } 536 } 537 LOGE("Data buffer slot is not available."); 538 return NULL; 539} 540 541void OMXVideoDecoderAVCSecure::MemFreeDataBuffer(OMX_U8 *pBuffer) { 542 DataBuffer *p = (DataBuffer*) pBuffer; 543 if (p == NULL) { 544 return; 545 } 546 for (int i = 0; i < INPORT_ACTUAL_BUFFER_COUNT; i++) { 547 if (pBuffer == mDataBufferSlot[i].owner) { 548 LOGV("Freeing Data buffer offset = %d, data = %#x", mDataBufferSlot[i].offset, (uint32_t)p->data); 549 delete [] p->data; 550 delete p; 551 mDataBufferSlot[i].owner = NULL; 552 return; 553 } 554 } 555 LOGE("Invalid buffer %#x to de-allocate", (uint32_t)pBuffer); 556} 557 558void OMXVideoDecoderAVCSecure::KeepAliveTimerCallback(sigval v) { 559 OMXVideoDecoderAVCSecure *p = (OMXVideoDecoderAVCSecure *)v.sival_ptr; 560 if (p) { 561 p->KeepAliveTimerCallback(); 562 } 563} 564 565void OMXVideoDecoderAVCSecure::KeepAliveTimerCallback() { 566 uint32_t timeout = DRM_KEEP_ALIVE_TIMER; 567 uint32_t sepres = drm_keep_alive(WV_SESSION_ID, &timeout); 568 if (sepres != 0) { 569 LOGE("Drm_KeepAlive failed. Result = %#x", sepres); 570 } 571} 572 573OMX_ERRORTYPE OMXVideoDecoderAVCSecure::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *p) { 574 OMX_ERRORTYPE ret; 575 CHECK_TYPE_HEADER(p); 576 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 577 578 p->nBufferCountActual = OUTPORT_NATIVE_BUFFER_COUNT; 579 return OMXVideoDecoderBase::SetMaxOutputBufferCount(p); 580} 581DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.AVC.secure", "video_decoder.avc", OMXVideoDecoderAVCSecure); 582