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