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