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