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