• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2009-2011 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "OMXVideoDecoder"
19 #include <wrs_omxil_core/log.h>
20 
21 #include <hardware/gralloc.h>
22 #include <va/va_android.h>
23 
24 #include "OMXVideoDecoderBase.h"
25 
26 static const char* VA_RAW_MIME_TYPE = "video/x-raw-va";
27 static const uint32_t VA_COLOR_FORMAT = 0x7FA00E00;
28 
OMXVideoDecoderBase()29 OMXVideoDecoderBase::OMXVideoDecoderBase()
30     : mRotationDegrees(0),
31 #ifdef TARGET_HAS_ISV
32       mVppBufferNum(0),
33 #endif
34       mCodecPriority(1),
35       mOperatingRate(0),
36       mVideoDecoder(NULL),
37       mNativeBufferCount(OUTPORT_NATIVE_BUFFER_COUNT),
38       mWorkingMode(RAWDATA_MODE),
39       mErrorReportEnabled (false),
40       mAPMode(LEGACY_MODE),
41       mFormatChanged(false) {
42       mOMXBufferHeaderTypePtrNum = 0;
43       mMetaDataBuffersNum = 0;
44       memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
45 }
46 
~OMXVideoDecoderBase()47 OMXVideoDecoderBase::~OMXVideoDecoderBase() {
48     releaseVideoDecoder(mVideoDecoder);
49 
50     if (this->ports) {
51         if (this->ports[INPORT_INDEX]) {
52             delete this->ports[INPORT_INDEX];
53             this->ports[INPORT_INDEX] = NULL;
54         }
55 
56         if (this->ports[OUTPORT_INDEX]) {
57             delete this->ports[OUTPORT_INDEX];
58             this->ports[OUTPORT_INDEX] = NULL;
59         }
60     }
61 }
62 
InitInputPort(void)63 OMX_ERRORTYPE OMXVideoDecoderBase::InitInputPort(void) {
64     this->ports[INPORT_INDEX] = new PortVideo;
65     if (this->ports[INPORT_INDEX] == NULL) {
66         return OMX_ErrorInsufficientResources;
67     }
68 
69     PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
70 
71     // OMX_PARAM_PORTDEFINITIONTYPE
72     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput;
73     memset(&paramPortDefinitionInput, 0, sizeof(paramPortDefinitionInput));
74     SetTypeHeader(&paramPortDefinitionInput, sizeof(paramPortDefinitionInput));
75     paramPortDefinitionInput.nPortIndex = INPORT_INDEX;
76     paramPortDefinitionInput.eDir = OMX_DirInput;
77     paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
78     paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
79     paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE;
80     paramPortDefinitionInput.bEnabled = OMX_TRUE;
81     paramPortDefinitionInput.bPopulated = OMX_FALSE;
82     paramPortDefinitionInput.eDomain = OMX_PortDomainVideo;
83     paramPortDefinitionInput.format.video.cMIMEType = NULL; // to be overridden
84     paramPortDefinitionInput.format.video.pNativeRender = NULL;
85     paramPortDefinitionInput.format.video.nFrameWidth = 176;
86     paramPortDefinitionInput.format.video.nFrameHeight = 144;
87     paramPortDefinitionInput.format.video.nStride = 0;
88     paramPortDefinitionInput.format.video.nSliceHeight = 0;
89     paramPortDefinitionInput.format.video.nBitrate = 64000;
90     paramPortDefinitionInput.format.video.xFramerate = 15 << 16;
91     // TODO: check if we need to set bFlagErrorConcealment  to OMX_TRUE
92     paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE;
93     paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden
94     paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatUnused;
95     paramPortDefinitionInput.format.video.pNativeWindow = NULL;
96     paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE;
97     paramPortDefinitionInput.nBufferAlignment = 0;
98 
99     // Derived class must implement this interface and override any field if needed.
100     // eCompressionFormat and and cMIMEType must be overridden
101     InitInputPortFormatSpecific(&paramPortDefinitionInput);
102 
103     port->SetPortDefinition(&paramPortDefinitionInput, true);
104 
105     // OMX_VIDEO_PARAM_PORTFORMATTYPE
106     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
107     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
108     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
109     paramPortFormat.nPortIndex = INPORT_INDEX;
110     paramPortFormat.nIndex = 0;
111     paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat;
112     paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat;
113     paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate;
114 
115     port->SetPortVideoParam(&paramPortFormat, true);
116 
117     return OMX_ErrorNone;
118 }
119 
120 
InitOutputPort(void)121 OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPort(void) {
122     this->ports[OUTPORT_INDEX] = new PortVideo;
123     if (this->ports[OUTPORT_INDEX] == NULL) {
124         return OMX_ErrorInsufficientResources;
125     }
126 
127     PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
128 
129     // OMX_PARAM_PORTDEFINITIONTYPE
130     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput;
131 
132     memset(&paramPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
133     SetTypeHeader(&paramPortDefinitionOutput, sizeof(paramPortDefinitionOutput));
134 
135     paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX;
136     paramPortDefinitionOutput.eDir = OMX_DirOutput;
137     paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT;
138     paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT;
139     paramPortDefinitionOutput.nBufferSize = sizeof(VideoRenderBuffer);
140 
141     paramPortDefinitionOutput.bEnabled = OMX_TRUE;
142     paramPortDefinitionOutput.bPopulated = OMX_FALSE;
143     paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo;
144     paramPortDefinitionOutput.format.video.cMIMEType = (OMX_STRING)VA_RAW_MIME_TYPE;
145     paramPortDefinitionOutput.format.video.pNativeRender = NULL;
146     paramPortDefinitionOutput.format.video.nFrameWidth = 176;
147     paramPortDefinitionOutput.format.video.nFrameHeight = 144;
148     paramPortDefinitionOutput.format.video.nStride = 176;
149     paramPortDefinitionOutput.format.video.nSliceHeight = 144;
150     paramPortDefinitionOutput.format.video.nBitrate = 64000;
151     paramPortDefinitionOutput.format.video.xFramerate = 15 << 16;
152     paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE;
153     paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
154     paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
155     paramPortDefinitionOutput.format.video.pNativeWindow = NULL;
156     paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE;
157     paramPortDefinitionOutput.nBufferAlignment = 0;
158 
159     // no format specific to initialize output port
160     InitOutputPortFormatSpecific(&paramPortDefinitionOutput);
161 
162     port->SetPortDefinition(&paramPortDefinitionOutput, true);
163 
164     // OMX_VIDEO_PARAM_PORTFORMATTYPE
165     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
166     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
167     paramPortFormat.nPortIndex = OUTPORT_INDEX;
168     paramPortFormat.nIndex = 0;
169     paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat;
170     paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat;
171     paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate;
172 
173     port->SetPortVideoParam(&paramPortFormat, true);
174 
175     return OMX_ErrorNone;
176 }
177 
InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *)178 OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) {
179     // no format specific to initialize output port
180     return OMX_ErrorNone;
181 }
182 
ProcessorInit(void)183 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorInit(void) {
184     OMX_ERRORTYPE ret;
185     ret = OMXComponentCodecBase::ProcessorInit();
186     CHECK_RETURN_VALUE("OMXComponentCodecBase::ProcessorInit");
187 
188     if (mVideoDecoder == NULL) {
189         LOGE("ProcessorInit: Video decoder is not created.");
190         return OMX_ErrorDynamicResourcesUnavailable;
191     }
192 
193     VideoConfigBuffer configBuffer;
194     ret = PrepareConfigBuffer(&configBuffer);
195     CHECK_RETURN_VALUE("PrepareConfigBuffer");
196 
197     //pthread_mutex_lock(&mSerializationLock);
198     Decode_Status status = mVideoDecoder->start(&configBuffer);
199     //pthread_mutex_unlock(&mSerializationLock);
200 
201     if (status != DECODE_SUCCESS) {
202         return TranslateDecodeStatus(status);
203     }
204 
205     return OMX_ErrorNone;
206 }
207 
ProcessorReset(void)208 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorReset(void) {
209     OMX_ERRORTYPE ret;
210     VideoConfigBuffer configBuffer;
211     // reset the configbuffer and set it to mix
212     ret = PrepareConfigBuffer(&configBuffer);
213     CHECK_RETURN_VALUE("PrepareConfigBuffer");
214     mVideoDecoder->reset(&configBuffer);
215     return OMX_ErrorNone;
216 }
217 
218 
ProcessorDeinit(void)219 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorDeinit(void) {
220     if (mWorkingMode != GRAPHICBUFFER_MODE) {
221         if (mVideoDecoder == NULL) {
222             LOGE("ProcessorDeinit: Video decoder is not created.");
223             return OMX_ErrorDynamicResourcesUnavailable;
224         }
225         mVideoDecoder->stop();
226     }
227     mOMXBufferHeaderTypePtrNum = 0;
228     memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
229     mRotationDegrees = 0;
230 #ifdef TARGET_HAS_ISV
231     mVppBufferNum = 0;
232 #endif
233     return OMXComponentCodecBase::ProcessorDeinit();
234 }
235 
ProcessorStart(void)236 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStart(void) {
237     return OMXComponentCodecBase::ProcessorStart();
238 }
239 
ProcessorStop(void)240 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStop(void) {
241     // There is no need to return all retained buffers as we don't accumulate buffer
242     //this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
243 
244     // TODO: this is new code
245     ProcessorFlush(OMX_ALL);
246     if (mWorkingMode == GRAPHICBUFFER_MODE) {
247         // for GRAPHICBUFFER_MODE mode, va_destroySurface need to lock the graphicbuffer,
248         // Make sure va_destroySurface is called(ExecutingToIdle) before graphicbuffer is freed(IdleToLoaded).
249         if (mVideoDecoder == NULL) {
250             LOGE("ProcessorStop: Video decoder is not created.");
251             return OMX_ErrorDynamicResourcesUnavailable;
252         }
253         mVideoDecoder->stop();
254     }
255     return OMXComponentCodecBase::ProcessorStop();
256 }
257 
ProcessorPause(void)258 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPause(void) {
259     return OMXComponentCodecBase::ProcessorPause();
260 }
261 
ProcessorResume(void)262 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorResume(void) {
263     return OMXComponentCodecBase::ProcessorResume();
264 }
265 
ProcessorFlush(OMX_U32 portIndex)266 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorFlush(OMX_U32 portIndex) {
267     LOGI("Flushing port# %u.", portIndex);
268     if (mVideoDecoder == NULL) {
269         LOGE("ProcessorFlush: Video decoder is not created.");
270         return OMX_ErrorDynamicResourcesUnavailable;
271     }
272 
273     // Portbase has returned all retained buffers.
274     if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) {
275         //pthread_mutex_lock(&mSerializationLock);
276         LOGW("Flushing video pipeline.");
277         mVideoDecoder->flush();
278         //pthread_mutex_unlock(&mSerializationLock);
279     }
280     // TODO: do we need to flush output port?
281     return OMX_ErrorNone;
282 }
283 
ProcessorPreFreeBuffer(OMX_U32 nPortIndex,OMX_BUFFERHEADERTYPE * pBuffer)284 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE * pBuffer) {
285     if (mWorkingMode == GRAPHICBUFFER_MODE)
286         return OMX_ErrorNone;
287 
288     if (nPortIndex == OUTPORT_INDEX && pBuffer->pPlatformPrivate) {
289         VideoRenderBuffer *p = (VideoRenderBuffer *)pBuffer->pPlatformPrivate;
290         p->renderDone = true;
291         pBuffer->pPlatformPrivate = NULL;
292     }
293     return OMX_ErrorNone;
294 }
295 
ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE * buffer)296  OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer) {
297     if (mWorkingMode == GRAPHICBUFFER_MODE && buffer->nOutputPortIndex == OUTPORT_INDEX){
298         Decode_Status status;
299         if(mVideoDecoder == NULL){
300             LOGW("ProcessorPreFillBuffer: Video decoder is not created");
301             return OMX_ErrorDynamicResourcesUnavailable;
302         }
303 
304         if (mAPMode == METADATA_MODE) {
305             bool found = false;
306             if (mOMXBufferHeaderTypePtrNum < mMetaDataBuffersNum) {
307                 for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++) {
308                     if (mOMXBufferHeaderTypePtrArray[i] == buffer) {
309                         found = true;
310                         break;
311                     }
312                 }
313                 if (!found) {
314                     mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum] = buffer;
315                     mOMXBufferHeaderTypePtrNum++;
316                 }
317             }
318 
319             VideoDecoderOutputMetaData *metadata = (VideoDecoderOutputMetaData *)(buffer->pBuffer);
320             status = mVideoDecoder->signalRenderDone((void *)(metadata->pHandle), !found);
321         } else {
322             status = mVideoDecoder->signalRenderDone(buffer->pBuffer);
323         }
324 
325         if (status != DECODE_SUCCESS) {
326             LOGW("ProcessorPreFillBuffer:: signalRenderDone return error");
327             return TranslateDecodeStatus(status);
328         }
329     } else if (buffer->pPlatformPrivate && buffer->nOutputPortIndex == OUTPORT_INDEX){
330         VideoRenderBuffer *p = (VideoRenderBuffer *)buffer->pPlatformPrivate;
331         p->renderDone = true;
332         buffer->pPlatformPrivate = NULL;
333     }
334     return OMX_ErrorNone;
335 }
336 
ProcessorProcess(OMX_BUFFERHEADERTYPE *** pBuffers,buffer_retain_t * retains,OMX_U32)337 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorProcess(
338     OMX_BUFFERHEADERTYPE ***pBuffers,
339     buffer_retain_t *retains,
340     OMX_U32) {
341 
342     OMX_ERRORTYPE ret;
343     Decode_Status status;
344     OMX_BOOL isResolutionChange = OMX_FALSE;
345     // fill render buffer without draining decoder output queue
346     ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX], 0, &isResolutionChange);
347     if (ret == OMX_ErrorNone) {
348         retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
349         if (isResolutionChange) {
350             HandleFormatChange();
351         }
352 
353         // Actually, if mAPMode is set, mWorkingMode should be GRAPHICBUFFER_MODE.
354         if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) {
355             if (((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS) || (mVideoDecoder->getOutputQueueLength() == 0)) {
356                 HandleFormatChange();
357             }
358         }
359 
360         // TODO: continue decoding
361         return ret;
362     } else if (ret != OMX_ErrorNotReady) {
363         return ret;
364     }
365 
366     VideoDecodeBuffer decodeBuffer;
367     // PrepareDecodeBuffer will set retain to either BUFFER_RETAIN_GETAGAIN or BUFFER_RETAIN_NOT_RETAIN
368     ret = PrepareDecodeBuffer(*pBuffers[INPORT_INDEX], &retains[INPORT_INDEX], &decodeBuffer);
369     if (ret == OMX_ErrorNotReady) {
370         retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
371         return OMX_ErrorNone;
372     } else if (ret != OMX_ErrorNone) {
373         return ret;
374     }
375 
376     if (decodeBuffer.size != 0) {
377         //pthread_mutex_lock(&mSerializationLock);
378         status = mVideoDecoder->decode(&decodeBuffer);
379         //pthread_mutex_unlock(&mSerializationLock);
380 
381         if (status == DECODE_FORMAT_CHANGE) {
382             if ((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) {
383                 mFormatChanged = true;
384                 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
385             } else {
386                 ret = HandleFormatChange();
387                 CHECK_RETURN_VALUE("HandleFormatChange");
388                 ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0;
389                 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
390                 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
391                 // real dynamic resolution change will be handled later
392                 // Here is just a temporary workaround
393                 // don't use the output buffer if format is changed.
394                 return OMX_ErrorNone;
395             }
396         } else if (status == DECODE_NO_CONFIG) {
397             LOGW("Decoder returns DECODE_NO_CONFIG.");
398             retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
399             return OMX_ErrorNone;
400         } else if (status == DECODE_NO_REFERENCE) {
401             LOGW("Decoder returns DECODE_NO_REFERENCE.");
402             //retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
403             //return OMX_ErrorNone;
404         } else if (status == DECODE_MULTIPLE_FRAME){
405             if (decodeBuffer.ext != NULL && decodeBuffer.ext->extType == PACKED_FRAME_TYPE && decodeBuffer.ext->extData != NULL) {
406                 PackedFrameData* nextFrame = (PackedFrameData*)decodeBuffer.ext->extData;
407                 (*pBuffers[INPORT_INDEX])->nOffset += nextFrame->offSet;
408                 (*pBuffers[INPORT_INDEX])->nTimeStamp = nextFrame->timestamp;
409                 (*pBuffers[INPORT_INDEX])->nFilledLen -= nextFrame->offSet;
410                 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
411                 LOGW("Find multiple frames in a buffer, next frame offset = %d, timestamp = %lld", (*pBuffers[INPORT_INDEX])->nOffset, (*pBuffers[INPORT_INDEX])->nTimeStamp);
412             }
413         }
414         else if (status != DECODE_SUCCESS && status != DECODE_FRAME_DROPPED) {
415             if (checkFatalDecoderError(status)) {
416                 return TranslateDecodeStatus(status);
417             } else {
418                 // For decoder errors that could be omitted,  not throw error and continue to decode.
419                 TranslateDecodeStatus(status);
420 
421                 ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0;
422 
423                 // Do not return, and try to drain the output queue
424                 // retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
425                 // return OMX_ErrorNone;
426             }
427         }
428     }
429     // drain the decoder output queue when in EOS state and fill the render buffer
430     ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX],
431             ((*pBuffers[INPORT_INDEX]))->nFlags,&isResolutionChange);
432 
433     if (isResolutionChange) {
434         HandleFormatChange();
435     }
436 
437     if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) {
438         if (((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS) || (mVideoDecoder->getOutputQueueLength() == 0)) {
439             HandleFormatChange();
440         }
441     }
442 
443     bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
444     bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
445     // if output port is not eos, retain the input buffer until all the output buffers are drained.
446     if (inputEoS && !outputEoS) {
447         retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
448         // the input buffer is retained for draining purpose. Set nFilledLen to 0 so buffer will not be decoded again.
449         (*pBuffers[INPORT_INDEX])->nFilledLen = 0;
450     }
451 
452     if (ret == OMX_ErrorNotReady) {
453         retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
454         ret = OMX_ErrorNone;
455     }
456 
457     return ret;
458 }
459 
IsAllBufferAvailable(void)460 bool OMXVideoDecoderBase::IsAllBufferAvailable(void) {
461     bool b = ComponentBase::IsAllBufferAvailable();
462     if (b == false) {
463         return false;
464     }
465 
466     PortVideo *port = NULL;
467     port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
468     const OMX_PARAM_PORTDEFINITIONTYPE* port_def = port->GetPortDefinition();
469      // if output port is disabled, retain the input buffer
470     if (!port_def->bEnabled) {
471         return false;
472     }
473 
474     if (mVideoDecoder) {
475         return mVideoDecoder->checkBufferAvail();
476     }
477     return false;
478 }
479 
PrepareConfigBuffer(VideoConfigBuffer * p)480 OMX_ERRORTYPE OMXVideoDecoderBase::PrepareConfigBuffer(VideoConfigBuffer *p) {
481     // default config buffer preparation
482     memset(p, 0, sizeof(VideoConfigBuffer));
483 
484     const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = this->ports[INPORT_INDEX]->GetPortDefinition();
485     if (paramPortDefinitionInput == NULL) {
486         return OMX_ErrorBadParameter;
487     }
488 
489     if (mWorkingMode == GRAPHICBUFFER_MODE) {
490         if (mAPMode == METADATA_MODE) {
491             const OMX_PARAM_PORTDEFINITIONTYPE *def_output = this->ports[OUTPORT_INDEX]->GetPortDefinition();
492             if (def_output == NULL) {
493                 return OMX_ErrorBadParameter;
494             }
495 
496             mMetaDataBuffersNum = def_output->nBufferCountActual;
497             mOMXBufferHeaderTypePtrNum = 0;
498 
499             mGraphicBufferParam.graphicBufferColorFormat = def_output->format.video.eColorFormat;
500             mGraphicBufferParam.graphicBufferStride = getStride(def_output->format.video.nFrameWidth);
501             mGraphicBufferParam.graphicBufferWidth = def_output->format.video.nFrameWidth;
502             mGraphicBufferParam.graphicBufferHeight = (def_output->format.video.nFrameHeight + 0xf) & ~0xf;
503 
504             p->surfaceNumber = mMetaDataBuffersNum;
505             for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
506                 p->graphicBufferHandler[i] = NULL;
507             }
508             p->flag |= WANT_STORE_META_DATA;
509         } else {
510             p->surfaceNumber = mOMXBufferHeaderTypePtrNum;
511             for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++){
512                 OMX_BUFFERHEADERTYPE *buffer_hdr = mOMXBufferHeaderTypePtrArray[i];
513                 p->graphicBufferHandler[i] = buffer_hdr->pBuffer;
514                 LOGV("PrepareConfigBuffer bufferid = %p, handle = %p", buffer_hdr, buffer_hdr->pBuffer);
515             }
516         }
517         p->flag |= USE_NATIVE_GRAPHIC_BUFFER;
518         p->graphicBufferStride = mGraphicBufferParam.graphicBufferStride;
519         p->graphicBufferColorFormat = mGraphicBufferParam.graphicBufferColorFormat;
520         p->graphicBufferWidth = mGraphicBufferParam.graphicBufferWidth;
521         p->graphicBufferHeight = mGraphicBufferParam.graphicBufferHeight;
522         if (p->graphicBufferColorFormat == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled
523 #ifdef USE_GEN_HW
524             || p->graphicBufferColorFormat == HAL_PIXEL_FORMAT_NV12_X_TILED_INTEL
525 #endif
526         )
527             p->flag |= USE_TILING_MEMORY;
528 
529         if (mEnableAdaptivePlayback)
530             p->flag |= WANT_ADAPTIVE_PLAYBACK;
531 
532         PortVideo *port = NULL;
533         port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
534         OMX_PARAM_PORTDEFINITIONTYPE port_def;
535         memcpy(&port_def, port->GetPortDefinition(), sizeof(port_def));
536 
537         if (port_def.format.video.pNativeWindow != NULL) {
538             p->nativeWindow = port_def.format.video.pNativeWindow;
539             LOGD("NativeWindow = %p", p->nativeWindow);
540         }
541 
542     }
543 
544     p->rotationDegrees = mRotationDegrees;
545 #ifdef TARGET_HAS_ISV
546     p->vppBufferNum = mVppBufferNum;
547 #endif
548     p->width = paramPortDefinitionInput->format.video.nFrameWidth;
549     p->height = paramPortDefinitionInput->format.video.nFrameHeight;
550 
551     return OMX_ErrorNone;
552 }
553 
PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE * buffer,buffer_retain_t * retain,VideoDecodeBuffer * p)554 OMX_ERRORTYPE OMXVideoDecoderBase::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) {
555     // default decode buffer preparation
556     memset(p, 0, sizeof(VideoDecodeBuffer));
557     if (buffer->nFilledLen == 0) {
558         LOGW("Len of filled data to decode is 0.");
559         return OMX_ErrorNone; //OMX_ErrorBadParameter;
560     }
561 
562     if (buffer->pBuffer == NULL) {
563         LOGE("Buffer to decode is empty.");
564         return OMX_ErrorBadParameter;
565     }
566 
567     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
568         LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag.");
569     }
570 
571     if (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) {
572         // TODO: Handle OMX_BUFFERFLAG_DECODEONLY : drop the decoded frame without rendering it.
573         LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag.");
574     }
575 
576     p->data = buffer->pBuffer + buffer->nOffset;
577     p->size = buffer->nFilledLen;
578     p->timeStamp = buffer->nTimeStamp;
579     if (buffer->nFlags & (OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS)) {
580         // TODO: OMX_BUFFERFLAG_ENDOFFRAME can be used to indicate end of a NAL unit.
581         // setting this flag may cause corruption if buffer does not contain end-of-frame data.
582         p->flag = HAS_COMPLETE_FRAME;
583     }
584 
585     if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME) {
586         p->flag |= IS_SYNC_FRAME;
587     }
588 
589     if (buffer->pInputPortPrivate) {
590         uint32_t degree = 0;
591         memcpy ((void *) &degree, buffer->pInputPortPrivate, sizeof(uint32_t));
592         p->rotationDegrees = degree;
593         LOGV("rotationDegrees = %d", p->rotationDegrees);
594     } else {
595         p->rotationDegrees = mRotationDegrees;
596     }
597 
598     *retain= BUFFER_RETAIN_NOT_RETAIN;
599     return OMX_ErrorNone;
600 }
601 
FillRenderBuffer(OMX_BUFFERHEADERTYPE ** pBuffer,buffer_retain_t * retain,OMX_U32 inportBufferFlags,OMX_BOOL * isResolutionChange)602 OMX_ERRORTYPE OMXVideoDecoderBase::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer, buffer_retain_t *retain, OMX_U32 inportBufferFlags, OMX_BOOL *isResolutionChange) {
603     OMX_BUFFERHEADERTYPE *buffer = *pBuffer;
604     OMX_BUFFERHEADERTYPE *buffer_orign = buffer;
605     VideoErrorBuffer *ErrBufPtr = NULL;
606 
607     if (mWorkingMode != GRAPHICBUFFER_MODE && buffer->pPlatformPrivate) {
608         VideoRenderBuffer *p = (VideoRenderBuffer *)buffer->pPlatformPrivate;
609         p->renderDone = true;
610         buffer->pPlatformPrivate = NULL;
611     }
612 
613     if (mWorkingMode == GRAPHICBUFFER_MODE && mErrorReportEnabled) {
614         if (buffer->pOutputPortPrivate == NULL)
615             LOGE("The App doesn't provide the output buffer for error reporting");
616         else
617             ErrBufPtr = (VideoErrorBuffer *)buffer->pOutputPortPrivate;
618     }
619 
620     bool draining = (inportBufferFlags & OMX_BUFFERFLAG_EOS);
621     //pthread_mutex_lock(&mSerializationLock);
622     const VideoRenderBuffer *renderBuffer;
623     //pthread_mutex_unlock(&mSerializationLock);
624     if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) {
625          renderBuffer = mVideoDecoder->getOutput(true, ErrBufPtr);
626     } else {
627          renderBuffer = mVideoDecoder->getOutput(draining, ErrBufPtr);
628     }
629     if (renderBuffer == NULL) {
630         buffer->nFilledLen = 0;
631         if (draining) {
632             LOGI("output EOS received");
633             buffer->nFlags = OMX_BUFFERFLAG_EOS;
634             return OMX_ErrorNone;
635         }
636         return OMX_ErrorNotReady;
637     }
638 
639     if (mWorkingMode == GRAPHICBUFFER_MODE) {
640         buffer = *pBuffer = mOMXBufferHeaderTypePtrArray[renderBuffer->graphicBufferIndex];
641      }
642 
643     buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
644 #ifdef DEINTERLACE_EXT
645     if (renderBuffer->scanFormat & (VA_TOP_FIELD | VA_BOTTOM_FIELD))
646         buffer->nFlags |= OMX_BUFFERFLAG_TFF;
647 #endif
648     buffer->nTimeStamp = renderBuffer->timeStamp;
649 
650     if (renderBuffer->flag & IS_EOS) {
651         buffer->nFlags |= OMX_BUFFERFLAG_EOS;
652     }
653     *isResolutionChange = (renderBuffer->flag & IS_RESOLUTION_CHANGE)? OMX_TRUE: OMX_FALSE;
654 
655     if (mWorkingMode == GRAPHICBUFFER_MODE) {
656         if (buffer_orign != buffer) {
657             VideoErrorBuffer *ErrBufOutPtr = NULL;
658             ErrBufOutPtr = (VideoErrorBuffer *)buffer->pOutputPortPrivate;
659             if (ErrBufPtr && ErrBufOutPtr) {
660                 memcpy(ErrBufOutPtr, ErrBufPtr, sizeof(VideoErrorBuffer));
661                 memset(ErrBufPtr, 0, sizeof(VideoErrorBuffer));
662             }
663             *retain = BUFFER_RETAIN_OVERRIDDEN;
664         }
665          buffer->nFilledLen = sizeof(OMX_U8*);
666     } else {
667         uint32_t size = 0;
668         Decode_Status status = mVideoDecoder->getRawDataFromSurface(const_cast<VideoRenderBuffer *>(renderBuffer), buffer->pBuffer + buffer->nOffset, &size, false);
669         if (status != DECODE_SUCCESS) {
670             return TranslateDecodeStatus(status);
671         }
672         buffer->nFilledLen = size;
673         buffer->pPlatformPrivate = (void *)renderBuffer;
674     }
675 
676     return OMX_ErrorNone;
677 }
678 
HandleFormatChange(void)679 OMX_ERRORTYPE OMXVideoDecoderBase::HandleFormatChange(void) {
680     LOGW("Video format is changed.");
681     //pthread_mutex_lock(&mSerializationLock);
682     const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo();
683     //pthread_mutex_unlock(&mSerializationLock);
684 
685     // Sync port definition as it may change.
686     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput;
687 
688     memcpy(&paramPortDefinitionInput,
689         this->ports[INPORT_INDEX]->GetPortDefinition(),
690         sizeof(paramPortDefinitionInput));
691 
692     memcpy(&paramPortDefinitionOutput,
693         this->ports[OUTPORT_INDEX]->GetPortDefinition(),
694         sizeof(paramPortDefinitionOutput));
695 
696     uint32_t width = formatInfo->width;
697     uint32_t height = formatInfo->height;
698     uint32_t stride = formatInfo->width;
699     uint32_t sliceHeight = formatInfo->height;
700 
701     uint32_t widthCropped = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight;
702     uint32_t heightCropped = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom;
703     uint32_t strideCropped = widthCropped;
704     uint32_t sliceHeightCropped = heightCropped;
705     int force_realloc = 0;
706     bool isVP8 = false;
707 
708     if (mAPMode == METADATA_MODE && mWorkingMode == GRAPHICBUFFER_MODE) {
709 #ifdef TARGET_HAS_ISV
710         if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) {
711 #else
712         if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) {
713 #endif
714             paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded;
715             paramPortDefinitionOutput.nBufferCountMin = formatInfo->actualBufferNeeded - 4;
716         }
717         // input port
718         paramPortDefinitionInput.format.video.nFrameWidth = width;
719         paramPortDefinitionInput.format.video.nFrameHeight = height;
720         paramPortDefinitionInput.format.video.nStride = stride;
721         paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight;
722         // output port
723         paramPortDefinitionOutput.format.video.nFrameWidth = width;
724         paramPortDefinitionOutput.format.video.nFrameHeight = (height + 0x1f) & ~0x1f;
725         paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(paramPortDefinitionOutput.format.video.nFrameWidth);
726         paramPortDefinitionOutput.format.video.nStride = stride;
727         paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight;
728 
729         paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false;
730         mOMXBufferHeaderTypePtrNum = 0;
731         memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
732         mMetaDataBuffersNum = 0;
733 
734         this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
735         this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, true);
736 
737         ProcessorFlush(INPORT_INDEX);
738 
739         mVideoDecoder->freeSurfaceBuffers();
740 
741         this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged();
742 
743         mFormatChanged = false;
744         return OMX_ErrorNone;
745     }
746 
747 #ifdef TARGET_HAS_ISV
748     LOGI("============== mVppBufferNum = %d\n", mVppBufferNum);
749     if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) {
750 #else
751     if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) {
752 #endif
753         if (mWorkingMode == GRAPHICBUFFER_MODE) {
754             LOGV("output port buffer number is not enough: %d to %d",
755                  paramPortDefinitionOutput.nBufferCountActual,
756                  formatInfo->actualBufferNeeded);
757             paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded;
758             paramPortDefinitionOutput.nBufferCountMin = mNativeBufferCount;
759             force_realloc = 1;
760         }
761     }
762 
763     LOGV("Original size = %u x %u, new size = %d x %d, cropped size = %d x %d",
764         paramPortDefinitionInput.format.video.nFrameWidth,
765         paramPortDefinitionInput.format.video.nFrameHeight,
766         width, height, widthCropped, heightCropped);
767 
768     if (paramPortDefinitionInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) {
769         isVP8 = true;
770     }
771 
772     if (!force_realloc &&
773         widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth &&
774         heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) {
775         if (mWorkingMode == RAWDATA_MODE) {
776             LOGW("Change of portsetting is not reported as size is not changed.");
777             return OMX_ErrorNone;
778         }
779     }
780 
781     paramPortDefinitionInput.format.video.nFrameWidth = width;
782     paramPortDefinitionInput.format.video.nFrameHeight = height;
783     paramPortDefinitionInput.format.video.nStride = stride;
784     paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight;
785 
786     if (mWorkingMode == RAWDATA_MODE) {
787         paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped;
788         paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped;
789         paramPortDefinitionOutput.format.video.nStride = strideCropped;
790         paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped;
791     } else if (mWorkingMode == GRAPHICBUFFER_MODE) {
792         // when the width and height ES parse are not larger than allocated graphic buffer in outport,
793         // there is no need to reallocate graphic buffer,just report the crop info to omx client
794         if (!force_realloc && width <= formatInfo->surfaceWidth && height <= formatInfo->surfaceHeight) {
795             this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
796             this->ports[OUTPORT_INDEX]->ReportOutputCrop();
797             return OMX_ErrorNone;
798         }
799 
800         if (isVP8 || width > formatInfo->surfaceWidth ||  height > formatInfo->surfaceHeight) {
801             // update the real decoded resolution to outport instead of display resolution for graphic buffer reallocation
802             // when the width and height parsed from ES are larger than allocated graphic buffer in outport,
803             paramPortDefinitionOutput.format.video.nFrameWidth = width;
804             paramPortDefinitionOutput.format.video.nFrameHeight = height;
805             paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(
806                     paramPortDefinitionOutput.format.video.nFrameWidth);
807             paramPortDefinitionOutput.format.video.nStride = stride;
808             paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight;
809        }
810     }
811 
812     paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false;
813     mOMXBufferHeaderTypePtrNum = 0;
814     memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
815 
816     this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
817     this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, true);
818 
819     if (mWorkingMode == GRAPHICBUFFER_MODE) {
820         // Make sure va_destroySurface is called before graphicbuffer is freed in case of port setting changed
821         mVideoDecoder->freeSurfaceBuffers();
822 
823         // Also make sure all the reference frames are flushed
824         ProcessorFlush(INPORT_INDEX);
825     }
826     this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged();
827     return OMX_ErrorNone;
828 }
829 
830 OMX_ERRORTYPE OMXVideoDecoderBase::TranslateDecodeStatus(Decode_Status status) {
831     switch (status) {
832         case DECODE_NEED_RESTART:
833             LOGE("Decoder returned DECODE_NEED_RESTART");
834             return (OMX_ERRORTYPE)OMX_ErrorIntelVideoNotPermitted;
835         case DECODE_NO_CONFIG:
836             LOGE("Decoder returned DECODE_NO_CONFIG");
837             return (OMX_ERRORTYPE)OMX_ErrorIntelMissingConfig;
838         case DECODE_NO_SURFACE:
839             LOGE("Decoder returned DECODE_NO_SURFACE");
840             return OMX_ErrorDynamicResourcesUnavailable;
841         case DECODE_NO_REFERENCE:
842             LOGE("Decoder returned DECODE_NO_REFERENCE");
843             return OMX_ErrorDynamicResourcesUnavailable; // TO DO
844         case DECODE_NO_PARSER:
845             LOGE("Decoder returned DECODE_NO_PARSER");
846             return OMX_ErrorDynamicResourcesUnavailable;
847         case DECODE_INVALID_DATA:
848             LOGE("Decoder returned DECODE_INVALID_DATA");
849             return OMX_ErrorBadParameter;
850         case DECODE_DRIVER_FAIL:
851             LOGE("Decoder returned DECODE_DRIVER_FAIL");
852             return OMX_ErrorHardware;
853         case DECODE_PARSER_FAIL:
854             LOGE("Decoder returned DECODE_PARSER_FAIL");
855             return (OMX_ERRORTYPE)OMX_ErrorIntelProcessStream; // OMX_ErrorStreamCorrupt
856         case DECODE_MEMORY_FAIL:
857             LOGE("Decoder returned DECODE_MEMORY_FAIL");
858             return OMX_ErrorInsufficientResources;
859         case DECODE_FAIL:
860             LOGE("Decoder returned DECODE_FAIL");
861             return OMX_ErrorUndefined;
862         case DECODE_SUCCESS:
863             return OMX_ErrorNone;
864         case DECODE_FORMAT_CHANGE:
865             LOGW("Decoder returned DECODE_FORMAT_CHANGE");
866             return OMX_ErrorNone;
867         case DECODE_FRAME_DROPPED:
868             LOGI("Decoder returned DECODE_FRAME_DROPPED");
869             return OMX_ErrorNone;
870         default:
871             LOGW("Decoder returned unknown error");
872             return OMX_ErrorUndefined;
873     }
874 }
875 
876 OMX_ERRORTYPE OMXVideoDecoderBase::BuildHandlerList(void) {
877     OMXComponentCodecBase::BuildHandlerList();
878     AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat);
879     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtGetNativeBufferUsage), GetNativeBufferUsage, SetNativeBufferUsage);
880     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer), GetNativeBuffer, SetNativeBuffer);
881     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer), GetNativeBufferMode, SetNativeBufferMode);
882     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees), GetDecoderRotation, SetDecoderRotation);
883 #ifdef TARGET_HAS_ISV
884     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum), GetDecoderVppBufferNum, SetDecoderVppBufferNum);
885 #endif
886     AddHandler(OMX_IndexConfigCommonOutputCrop, GetDecoderOutputCrop, SetDecoderOutputCrop);
887 #ifdef USE_META_DATA
888     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexStoreMetaDataInBuffers), GetStoreMetaDataMode, SetStoreMetaDataMode);
889 #endif
890     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport), GetErrorReportMode, SetErrorReportMode);
891     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexConfigPriority), GetCodecPriority, SetCodecPriority);
892     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexConfigOperatingRate), GetDecoderOperatingRate, SetDecoderOperatingRate);
893 
894     return OMX_ErrorNone;
895 }
896 
897 OMX_ERRORTYPE OMXVideoDecoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) {
898     OMX_ERRORTYPE ret;
899     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
900 
901     CHECK_TYPE_HEADER(p);
902     CHECK_PORT_INDEX_RANGE(p);
903     CHECK_ENUMERATION_RANGE(p->nIndex, 1);
904 
905     PortVideo *port = NULL;
906     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
907     memcpy(p, port->GetPortVideoParam(), sizeof(*p));
908     return OMX_ErrorNone;
909 }
910 
911 OMX_ERRORTYPE OMXVideoDecoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) {
912     OMX_ERRORTYPE ret;
913     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
914 
915     CHECK_TYPE_HEADER(p);
916     CHECK_PORT_INDEX_RANGE(p);
917     CHECK_SET_PARAM_STATE();
918 
919     // TODO: do we need to check if port is enabled?
920     PortVideo *port = NULL;
921     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
922     port->SetPortVideoParam(p, false);
923     return OMX_ErrorNone;
924 }
925 
926 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsageSpecific(OMX_PTR pStructure) {
927      OMX_ERRORTYPE ret;
928      GetAndroidNativeBufferUsageParams *param = (GetAndroidNativeBufferUsageParams*)pStructure;
929      CHECK_TYPE_HEADER(param);
930      // hardware usage: consumed by GLES and HWC
931      param->nUsage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER;
932      // software usage: can be read/written by apps
933      param->nUsage |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY;
934      return OMX_ErrorNone;
935 }
936 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsageSpecific(OMX_PTR) {
937     CHECK_SET_PARAM_STATE();
938     return OMX_ErrorBadParameter;
939 }
940 
941 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsage(OMX_PTR pStructure) {
942     return this->GetNativeBufferUsageSpecific(pStructure);
943 }
944 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsage(OMX_PTR pStructure) {
945     return this->SetNativeBufferUsageSpecific(pStructure);
946 }
947 
948 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBuffer(OMX_PTR) {
949     return OMX_ErrorBadParameter;
950 }
951 
952 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBuffer(OMX_PTR pStructure) {
953     OMX_ERRORTYPE ret;
954     UseAndroidNativeBufferParams *param = (UseAndroidNativeBufferParams*)pStructure;
955     CHECK_TYPE_HEADER(param);
956     if (param->nPortIndex != OUTPORT_INDEX)
957         return OMX_ErrorBadParameter;
958     OMX_BUFFERHEADERTYPE **buf_hdr = NULL;
959 
960     mOMXBufferHeaderTypePtrNum++;
961     if (mOMXBufferHeaderTypePtrNum > MAX_GRAPHIC_BUFFER_NUM)
962         return OMX_ErrorOverflow;
963 
964     buf_hdr = &mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum-1];
965 
966     ret = this->ports[OUTPORT_INDEX]->UseBuffer(buf_hdr, OUTPORT_INDEX, param->pAppPrivate, sizeof(OMX_U8*),
967                                       const_cast<OMX_U8*>(reinterpret_cast<const OMX_U8*>(param->nativeBuffer->handle)));
968     if (ret != OMX_ErrorNone)
969         return ret;
970 
971     if (mOMXBufferHeaderTypePtrNum == 1) {
972          mGraphicBufferParam.graphicBufferColorFormat = param->nativeBuffer->format;
973          mGraphicBufferParam.graphicBufferStride = param->nativeBuffer->stride;
974          mGraphicBufferParam.graphicBufferWidth = param->nativeBuffer->width;
975          mGraphicBufferParam.graphicBufferHeight = param->nativeBuffer->height;
976     }
977 
978     *(param->bufferHeader) = *buf_hdr;
979 
980     return OMX_ErrorNone;
981 }
982 
983 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferMode(OMX_PTR pStructure) {
984     return this->GetNativeBufferModeSpecific(pStructure);
985 }
986 
987 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferMode(OMX_PTR pStructure) {
988     return this->SetNativeBufferModeSpecific(pStructure);
989 }
990 
991 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferModeSpecific(OMX_PTR) {
992     LOGE("GetNativeBufferMode is not implemented");
993     return OMX_ErrorNotImplemented;
994 }
995 
996 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferModeSpecific(OMX_PTR pStructure) {
997     OMX_ERRORTYPE ret;
998     EnableAndroidNativeBuffersParams *param = (EnableAndroidNativeBuffersParams*)pStructure;
999 
1000     CHECK_TYPE_HEADER(param);
1001     CHECK_PORT_INDEX_RANGE(param);
1002     CHECK_SET_PARAM_STATE();
1003 
1004     PortVideo *port = NULL;
1005     port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
1006     OMX_PARAM_PORTDEFINITIONTYPE port_def;
1007     memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def));
1008 
1009     if (!param->enable) {
1010         mWorkingMode = RAWDATA_MODE;
1011         // If it is fallback from native mode the color format has been
1012         // already set to INTEL format.
1013         // We need to set back the default color format and Native stuff.
1014         port_def.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1015         port_def.format.video.pNativeRender = NULL;
1016         port_def.format.video.pNativeWindow = NULL;
1017         port->SetPortDefinition(&port_def,true);
1018         return OMX_ErrorNone;
1019     }
1020 
1021     mWorkingMode = GRAPHICBUFFER_MODE;
1022     port_def.nBufferCountMin = mNativeBufferCount;
1023     if (mEnableAdaptivePlayback) {
1024         SetMaxOutputBufferCount(&port_def);
1025     } else {
1026         port_def.nBufferCountActual = mNativeBufferCount;
1027     }
1028     port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE;
1029     port_def.format.video.eColorFormat = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar;
1030     port_def.format.video.nFrameHeight = (port_def.format.video.nFrameHeight + 0x1f) & ~0x1f;
1031     port_def.format.video.eColorFormat = GetOutputColorFormat(
1032                         port_def.format.video.nFrameWidth);
1033     port->SetPortDefinition(&port_def,true);
1034 
1035     return OMX_ErrorNone;
1036 }
1037 
1038 OMX_ERRORTYPE OMXVideoDecoderBase::GetStoreMetaDataMode(OMX_PTR) {
1039     ALOGE("GetMetaDataMode is not implemented");
1040     return OMX_ErrorNotImplemented;
1041 }
1042 
1043 OMX_ERRORTYPE OMXVideoDecoderBase::SetStoreMetaDataMode(OMX_PTR pStructure) {
1044 #ifndef USE_META_DATA
1045     OMX_PARAM_PORTDEFINITIONTYPE defInput;
1046     memcpy(&defInput,
1047         this->ports[INPORT_INDEX]->GetPortDefinition(),
1048         sizeof(defInput));
1049     if (defInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP9) {
1050         ALOGE("SetMetaDataMode for VP9 is not implemented");
1051         return OMX_ErrorNotImplemented;
1052     }
1053 #endif
1054     OMX_ERRORTYPE ret;
1055     StoreMetaDataInBuffersParams *param = (StoreMetaDataInBuffersParams*)pStructure;
1056 
1057     CHECK_TYPE_HEADER(param);
1058     CHECK_PORT_INDEX(param, OUTPORT_INDEX);
1059     CHECK_SET_PARAM_STATE();
1060 
1061     if (!param->bStoreMetaData) {
1062         mAPMode = LEGACY_MODE;
1063         // Don't return error which otherwise may cause framework crash
1064         return OMX_ErrorNone;
1065     }
1066     mAPMode = METADATA_MODE;
1067     ALOGI("We are in meta data mode!!!");
1068 
1069     return OMX_ErrorNone;
1070 }
1071 
1072 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderRotation(OMX_PTR) {
1073     return OMX_ErrorBadParameter;
1074 }
1075 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderRotation(OMX_PTR pStructure) {
1076     CHECK_SET_PARAM_STATE();
1077     int32_t rotationDegrees = 0;
1078 
1079     if (pStructure) {
1080         rotationDegrees = *(static_cast<int32_t*>(pStructure));
1081         mRotationDegrees = rotationDegrees;
1082         LOGI("Rotation Degree = %d", rotationDegrees);
1083         return OMX_ErrorNone;
1084     } else {
1085         return OMX_ErrorBadParameter;
1086     }
1087 }
1088 
1089 #ifdef TARGET_HAS_ISV
1090 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderVppBufferNum(OMX_PTR) {
1091     return OMX_ErrorBadParameter;
1092 }
1093 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderVppBufferNum(OMX_PTR pStructure) {
1094     CHECK_SET_PARAM_STATE();
1095     int32_t num = 0;
1096 
1097     num = *(static_cast<int32_t*>(pStructure));
1098     mVppBufferNum = num;
1099 
1100     return OMX_ErrorNone;
1101 }
1102 #endif
1103 
1104 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCropSpecific(OMX_PTR pStructure) {
1105     OMX_ERRORTYPE ret;
1106     OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)pStructure;
1107 
1108     CHECK_TYPE_HEADER(rectParams);
1109 
1110     if (rectParams->nPortIndex != OUTPORT_INDEX) {
1111         return OMX_ErrorUndefined;
1112     }
1113 
1114     PortVideo *port = NULL;
1115     port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
1116     OMX_PARAM_PORTDEFINITIONTYPE port_def;
1117     memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def));
1118 
1119     const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo();
1120     if (formatInfo->valid == true) {
1121         rectParams->nLeft =  formatInfo->cropLeft;
1122         rectParams->nTop = formatInfo->cropTop;
1123         rectParams->nWidth = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight;
1124         rectParams->nHeight = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom;
1125 
1126         // if port width parsed from extractor is not as same as from SPS/PPS nalu header,
1127         // align it.
1128         if (port_def.format.video.nFrameWidth != rectParams->nWidth) {
1129             port_def.format.video.nFrameWidth = rectParams->nWidth;
1130         }
1131         port->SetPortDefinition(&port_def,true);
1132         return OMX_ErrorNone;
1133     } else {
1134         return OMX_ErrorFormatNotDetected;
1135     }
1136 }
1137 
1138 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCropSpecific(OMX_PTR) {
1139     return OMX_ErrorUnsupportedSetting;
1140 }
1141 
1142 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCrop(OMX_PTR pStructure) {
1143     return this->SetDecoderOutputCropSpecific(pStructure);
1144 }
1145 
1146 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCrop(OMX_PTR pStructure) {
1147     return this->GetDecoderOutputCropSpecific(pStructure);
1148 }
1149 
1150 
1151 OMX_ERRORTYPE OMXVideoDecoderBase::SetCodecPriority(OMX_PTR pStructure) {
1152     OMX_ERRORTYPE ret;
1153     OMX_PARAM_U32TYPE *priorityParam = (OMX_PARAM_U32TYPE *)pStructure;
1154     mCodecPriority = priorityParam->nU32;
1155     return OMX_ErrorNone;
1156 }
1157 
1158 
1159 OMX_ERRORTYPE OMXVideoDecoderBase::GetCodecPriority(OMX_PTR pStructure) {
1160     OMX_ERRORTYPE ret;
1161     OMX_PARAM_U32TYPE *priorityParam = (OMX_PARAM_U32TYPE *)pStructure;
1162     CHECK_TYPE_HEADER(priorityParam);
1163     priorityParam->nU32 = mCodecPriority;
1164     return OMX_ErrorNone;
1165 }
1166 
1167 
1168 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOperatingRate(OMX_PTR pStructure) {
1169     OMX_ERRORTYPE ret;
1170     OMX_PARAM_U32TYPE *operatingRateParam = (OMX_PARAM_U32TYPE *)pStructure;
1171     CHECK_TYPE_HEADER(operatingRateParam);
1172     mOperatingRate = operatingRateParam->nU32;
1173     return OMX_ErrorNone;
1174 }
1175 
1176 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOperatingRate(OMX_PTR pStructure) {
1177     OMX_ERRORTYPE ret;
1178     OMX_PARAM_U32TYPE *operatingRateParam = (OMX_PARAM_U32TYPE *)pStructure;
1179     CHECK_TYPE_HEADER(operatingRateParam);
1180     operatingRateParam->nU32 = mOperatingRate;
1181     return OMX_ErrorNone;
1182 }
1183 
1184 OMX_ERRORTYPE OMXVideoDecoderBase::GetErrorReportMode(OMX_PTR) {
1185     LOGE("GetErrorReportMode is not implemented");
1186     return OMX_ErrorNotImplemented;
1187 }
1188 
1189 OMX_ERRORTYPE OMXVideoDecoderBase::SetErrorReportMode(OMX_PTR pStructure) {
1190     OMX_ERRORTYPE ret;
1191 
1192     OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *p = (OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *)pStructure;
1193     CHECK_TYPE_HEADER(p);
1194     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
1195 
1196     mErrorReportEnabled = p->bEnable;
1197     LOGD("Error reporting is %s", mErrorReportEnabled ? "enabled" : "disabled");
1198 
1199     mVideoDecoder->enableErrorReport(mErrorReportEnabled);
1200     return OMX_ErrorNone;
1201 }
1202 
1203 OMX_COLOR_FORMATTYPE OMXVideoDecoderBase::GetOutputColorFormat(int width) {
1204 #ifndef VED_TILING
1205     return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar;
1206 #else
1207     if (width > 1280 && width <= 2048) {
1208         LOGI("HD Video and use tiled format");
1209         return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled;
1210     } else {
1211         return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar;
1212     }
1213 #endif
1214 }
1215 
1216 OMX_ERRORTYPE OMXVideoDecoderBase::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *) {
1217     return OMX_ErrorNone;
1218 }
1219 
1220 uint32_t OMXVideoDecoderBase::getStride(uint32_t width) {
1221     uint32_t stride = 0;
1222 
1223     if (width <= 512)
1224         stride = 512;
1225     else if (width <= 1024)
1226         stride = 1024;
1227     else if (width <= 1280) {
1228         stride = 1280;
1229     } else if (width <= 2048)
1230         stride = 2048;
1231     else if (width <= 4096)
1232         stride = 4096;
1233     else
1234         stride = (width + 0x3f) & ~0x3f;
1235 
1236     return stride;
1237 }
1238