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