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(¶mPortDefinitionInput, 0, sizeof(paramPortDefinitionInput));
69 SetTypeHeader(¶mPortDefinitionInput, 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(¶mPortDefinitionInput);
97
98 port->SetPortDefinition(¶mPortDefinitionInput, true);
99
100 // OMX_VIDEO_PARAM_PORTFORMATTYPE
101 OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
102 memset(¶mPortFormat, 0, sizeof(paramPortFormat));
103 SetTypeHeader(¶mPortFormat, 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(¶mPortFormat, 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(¶mPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
128 SetTypeHeader(¶mPortDefinitionOutput, 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(¶mPortDefinitionOutput);
156
157 port->SetPortDefinition(¶mPortDefinitionOutput, true);
158
159 // OMX_VIDEO_PARAM_PORTFORMATTYPE
160 OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
161 SetTypeHeader(¶mPortFormat, 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(¶mPortFormat, 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 *) °ree, 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(¶mPortDefinitionInput,
620 this->ports[INPORT_INDEX]->GetPortDefinition(),
621 sizeof(paramPortDefinitionInput));
622
623 memcpy(¶mPortDefinitionOutput,
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(¶mPortDefinitionInput, 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(¶mPortDefinitionInput, true);
709 this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, 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