1e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu/*
2e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
3e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu*
4e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* Licensed under the Apache License, Version 2.0 (the "License");
5e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* you may not use this file except in compliance with the License.
6e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* You may obtain a copy of the License at
7e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu*
8e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* http://www.apache.org/licenses/LICENSE-2.0
9e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu*
10e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* Unless required by applicable law or agreed to in writing, software
11e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* distributed under the License is distributed on an "AS IS" BASIS,
12e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* See the License for the specific language governing permissions and
14e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* limitations under the License.
15e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu*/
16e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
17e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
1854272c0e474f97ac0269706170eb9161b36a9170wgu// #define LOG_NDEBUG 0
19bcabe3079546f97c7e2dc72886e55fabaff51848Andy Qiu#define LOG_TAG "OMXVideoDecoder"
2026a110c2a29667599733db5173a751e670b366a5Thierry Strudel#include <wrs_omxil_core/log.h>
21e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu#include "OMXVideoDecoderAVC.h"
22e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
23b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao
24e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu// Be sure to have an equal string in VideoDecoderHost.cpp (libmix)
25e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiustatic const char* AVC_MIME_TYPE = "video/h264";
26e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu#define INVALID_PTS (OMX_S64)-1
27e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
28e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
29e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMXVideoDecoderAVC::OMXVideoDecoderAVC()
30e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    : mAccumulateBuffer(NULL),
31e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu      mBufferSize(0),
32e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu      mFilledLen(0),
33e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu      mTimeStamp(INVALID_PTS) {
34e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    LOGV("OMXVideoDecoderAVC is constructed.");
35e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mVideoDecoder = createVideoDecoder(AVC_MIME_TYPE);
36e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (!mVideoDecoder) {
37e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        LOGE("createVideoDecoder failed for \"%s\"", AVC_MIME_TYPE);
38e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
39747c717e9477b5b660f39a2b737de5e968fa7f9dWeian Chen    // Override default native buffer count defined in the base class
40747c717e9477b5b660f39a2b737de5e968fa7f9dWeian Chen    mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT;
41e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    BuildHandlerList();
42e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
43e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
44e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMXVideoDecoderAVC::~OMXVideoDecoderAVC() {
45e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    LOGV("OMXVideoDecoderAVC is destructed.");
46e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
47e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
48e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) {
49e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    //OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS
50e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    memset(&mDecodeSettings, 0, sizeof(mDecodeSettings));
51e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    SetTypeHeader(&mDecodeSettings, sizeof(mDecodeSettings));
52e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mDecodeSettings.nMaxNumberOfReferenceFrame = NUM_REFERENCE_FRAME;
53e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
54e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // OMX_PARAM_PORTDEFINITIONTYPE
55e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
56e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
57e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE;
58e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE;
59e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
60e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
61e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // OMX_VIDEO_PARAM_AVCTYPE
62e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    memset(&mParamAvc, 0, sizeof(mParamAvc));
63e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    SetTypeHeader(&mParamAvc, sizeof(mParamAvc));
64e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mParamAvc.nPortIndex = INPORT_INDEX;
65e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // TODO: check eProfile/eLevel
66e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mParamAvc.eProfile = OMX_VIDEO_AVCProfileHigh; //OMX_VIDEO_AVCProfileBaseline;
67e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mParamAvc.eLevel = OMX_VIDEO_AVCLevel41; //OMX_VIDEO_AVCLevel1;
68e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
69e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
70e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
71e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
72e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorInit(void) {
73e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMXVideoDecoderBase::ProcessorInit();
74e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
75e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
76e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorDeinit(void) {
77e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (mAccumulateBuffer) {
78e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        delete mAccumulateBuffer;
79e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
80e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mAccumulateBuffer = NULL;
81e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mBufferSize = 0;
82e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mFilledLen = 0;
83e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mTimeStamp = INVALID_PTS;
84e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
85e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMXVideoDecoderBase::ProcessorDeinit();
86e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
87e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
88e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorFlush(OMX_U32 portIndex) {
89e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mFilledLen = 0;
90e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mTimeStamp = INVALID_PTS;
91e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMXVideoDecoderBase::ProcessorFlush(portIndex);
92e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
93e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
94e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorProcess(
95b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao        OMX_BUFFERHEADERTYPE ***pBuffers,
96e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        buffer_retain_t *retains,
97e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        OMX_U32 numberBuffers) {
98e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
99b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao    return OMXVideoDecoderBase::ProcessorProcess(pBuffers, retains, numberBuffers);
100e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
101e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
102e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::PrepareConfigBuffer(VideoConfigBuffer *p) {
103e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_ERRORTYPE ret;
104c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen
1058332b6aabd6694874a3269850c6d6f62fd76896dWeian Chen    ret = OMXVideoDecoderBase::PrepareConfigBuffer(p);
1068332b6aabd6694874a3269850c6d6f62fd76896dWeian Chen    CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareConfigBuffer");
1078332b6aabd6694874a3269850c6d6f62fd76896dWeian Chen
108c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen    if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileBaseline) {
109c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen        p->flag |= WANT_LOW_DELAY;
110c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen    }
111c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen
112e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (mDecodeSettings.nMaxWidth == 0 ||
113e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        mDecodeSettings.nMaxHeight == 0) {
114e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        return OMX_ErrorNone;
115e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
116e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
117e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    LOGW("AVC Video decoder used in Video Conferencing Mode.");
118e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
119e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // For video conferencing application
120e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    p->width = mDecodeSettings.nMaxWidth;
121e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    p->height = mDecodeSettings.nMaxHeight;
122e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    p->profile = VAProfileH264ConstrainedBaseline;
123b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao    if(!(p->flag & USE_NATIVE_GRAPHIC_BUFFER)) {
124b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao        p->surfaceNumber = mDecodeSettings.nMaxNumberOfReferenceFrame + EXTRA_REFERENCE_FRAME;
125b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao        p->flag = WANT_ERROR_CONCEALMENT | WANT_LOW_DELAY | HAS_SURFACE_NUMBER | HAS_VA_PROFILE;
126b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao    } else {
127b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao        p->flag |= WANT_ERROR_CONCEALMENT | WANT_LOW_DELAY | HAS_SURFACE_NUMBER | HAS_VA_PROFILE;
128b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao    }
129e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
130e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
131e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
132e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
133e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) {
134e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_ERRORTYPE ret;
135e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    ret = OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p);
136e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareDecodeBuffer");
137e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
138e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // OMX_BUFFERFLAG_CODECCONFIG is an optional flag
139e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // if flag is set, buffer will only contain codec data.
140e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
141e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        LOGV("Received AVC codec data.");
142e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        return ret;
143e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
144e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
145e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // OMX_BUFFERFLAG_ENDOFFRAME is an optional flag
1467951f06f8e3b6a91d385508b6f24720bc382df96ywan    if (buffer->nFlags & (OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS)) {
147e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // TODO: if OMX_BUFFERFLAG_ENDOFFRAME indicates end of a NAL unit and in OMXVideoDecodeBase
148e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // we set buffer flag to HAS_COMPLETE_FRAME,  corruption will happen
149e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        mTimeStamp = buffer->nTimeStamp;
150e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        if (mFilledLen == 0) {
151e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            // buffer is not accumulated and it contains a complete frame
152e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            return ret;
153e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        }
154e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // buffer contains  the last part of fragmented frame
155e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        ret = AccumulateBuffer(buffer);
156e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        CHECK_RETURN_VALUE("AccumulateBuffer");
157e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        ret = FillDecodeBuffer(p);
158e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        CHECK_RETURN_VALUE("FillDecodeBuffer");
159e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        return ret;
160e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
161e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
162e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    LOGW("Received fragmented buffer.");
163e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // use time stamp to determine frame boundary
164e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (mTimeStamp == INVALID_PTS) {
165e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // first ever buffer
166e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        mTimeStamp = buffer->nTimeStamp;
167e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
168e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
169e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (mTimeStamp != buffer->nTimeStamp && mFilledLen != 0) {
170e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // buffer accumulated contains a complete frame
171e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        ret = FillDecodeBuffer(p);
172e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        CHECK_RETURN_VALUE("FillDecodeBuffer");
173e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // retain the current buffer
174e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        *retain = BUFFER_RETAIN_GETAGAIN;
175e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    } else {
176e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // buffer accumulation for beginning of fragmented buffer (mFilledLen == 0) or
177e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // middle/end of fragmented buffer (mFilledLen != 0)
178e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        ret = AccumulateBuffer(buffer);
179e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        CHECK_RETURN_VALUE("AccumulateBuffer");
180e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        ret = OMX_ErrorNotReady;
181e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
182e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
183e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (buffer->nFilledLen != 0) {
184e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        mTimeStamp = buffer->nTimeStamp;
185e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
186e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return ret;
187e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
188e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
189e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::AccumulateBuffer(OMX_BUFFERHEADERTYPE *buffer) {
190e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // check if allocated buffer is big enough
191e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (mFilledLen + buffer->nFilledLen > mBufferSize) {
192e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        mBufferSize = mFilledLen + buffer->nFilledLen;
193e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        if (mBufferSize < INPORT_BUFFER_SIZE) {
194e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            mBufferSize = INPORT_BUFFER_SIZE;
195e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        }
196e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        if (mBufferSize == 0) {
197e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            return OMX_ErrorBadParameter;
198e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        }
199e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        OMX_U8 *temp = new OMX_U8 [mBufferSize];
200e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        if (temp == NULL) {
201e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            mBufferSize = 0;
202e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            return OMX_ErrorInsufficientResources;
203e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        }
204e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        if (mFilledLen != 0) {
205e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            memcpy(temp, mAccumulateBuffer, mFilledLen);
206e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        }
207e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        if (mAccumulateBuffer) {
208e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu            delete [] mAccumulateBuffer;
209e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        }
210e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        mAccumulateBuffer = temp;
211e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
212e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if (buffer->nFilledLen != 0) {
213e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        memcpy(mAccumulateBuffer + mFilledLen, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
214e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
215e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mFilledLen += buffer->nFilledLen;
216e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
217e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
218e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
219e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::FillDecodeBuffer(VideoDecodeBuffer *p) {
220e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    p->data = mAccumulateBuffer;
221e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    p->size = mFilledLen;
222e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    p->timeStamp = mTimeStamp;
223e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    p->flag = HAS_COMPLETE_FRAME;
224e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
225e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mFilledLen = 0;
226e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
227e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
228e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
229e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::BuildHandlerList(void) {
230e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMXVideoDecoderBase::BuildHandlerList();
231e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc);
232e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelAVCDecodeSettings, GetParamIntelAVCDecodeSettings, SetParamIntelAVCDecodeSettings);
2336bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoAVCProfileLevel, SetParamVideoAVCProfileLevel);
234e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
235e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
236e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
237e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::GetParamVideoAvc(OMX_PTR pStructure) {
238e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_ERRORTYPE ret;
239e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure;
240e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_TYPE_HEADER(p);
241e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_PORT_INDEX(p, INPORT_INDEX);
242e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
243e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    memcpy(p, &mParamAvc, sizeof(*p));
244e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
245e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
246e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
247e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::SetParamVideoAvc(OMX_PTR pStructure) {
248e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_ERRORTYPE ret;
249e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure;
250e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_TYPE_HEADER(p);
251e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_PORT_INDEX(p, INPORT_INDEX);
252e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_SET_PARAM_STATE();
253e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
254e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // TODO: do we need to check if port is enabled?
255e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    // TODO: see SetPortAvcParam implementation - Can we make simple copy????
256e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    memcpy(&mParamAvc, p, sizeof(mParamAvc));
257f775da472a8f0a626b0615eb283d614e0893f816Weian Chen
258e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
259e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
260e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
2610541f11be2f78b558476772f1f877e140f9d844bywanOMX_ERRORTYPE OMXVideoDecoderAVC::GetParamIntelAVCDecodeSettings(OMX_PTR) {
262e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNotImplemented;
263e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
264e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
265e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::SetParamIntelAVCDecodeSettings(OMX_PTR pStructure) {
266e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    LOGW("SetParamIntelAVCDecodeSettings");
267e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
268e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_ERRORTYPE ret;
269e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS *p = (OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS *)pStructure;
270e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
271e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_TYPE_HEADER(p);
272e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_PORT_INDEX(p, INPORT_INDEX);
273e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    CHECK_SET_PARAM_STATE();
274e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
275e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    if(p->nMaxNumberOfReferenceFrame == 0) {
276e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        // TODO: check if we just return in this case.
277e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu        p->nMaxNumberOfReferenceFrame = NUM_REFERENCE_FRAME;
278e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    }
2790541f11be2f78b558476772f1f877e140f9d844bywan    LOGI("Maximum width = %u, height = %u, dpb = %u", p->nMaxWidth, p->nMaxHeight, p->nMaxNumberOfReferenceFrame);
280e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    mDecodeSettings = *p;
281e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
282e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu    return OMX_ErrorNone;
283e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu}
284e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
2856bc8d027bb46c0638d26b3f755350b84f6325de3wfengOMX_ERRORTYPE OMXVideoDecoderAVC::GetParamVideoAVCProfileLevel(OMX_PTR pStructure) {
2866bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    OMX_ERRORTYPE ret;
2876bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure;
2886bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    CHECK_TYPE_HEADER(p);
2896bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    CHECK_PORT_INDEX(p, INPORT_INDEX);
2906bc8d027bb46c0638d26b3f755350b84f6325de3wfeng
29154272c0e474f97ac0269706170eb9161b36a9170wgu    struct ProfileLevelTable {
29254272c0e474f97ac0269706170eb9161b36a9170wgu        OMX_U32 profile;
29354272c0e474f97ac0269706170eb9161b36a9170wgu        OMX_U32 level;
29454272c0e474f97ac0269706170eb9161b36a9170wgu    } plTable[] = {
295d8c394df484c6fda8009b7c5d51166e271d3d2bdGu, Wangyi        {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42},
296d8c394df484c6fda8009b7c5d51166e271d3d2bdGu, Wangyi        {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42},
297d8c394df484c6fda8009b7c5d51166e271d3d2bdGu, Wangyi        {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}
29854272c0e474f97ac0269706170eb9161b36a9170wgu    };
29954272c0e474f97ac0269706170eb9161b36a9170wgu
30054272c0e474f97ac0269706170eb9161b36a9170wgu    OMX_U32 count = sizeof(plTable)/sizeof(ProfileLevelTable);
30154272c0e474f97ac0269706170eb9161b36a9170wgu    CHECK_ENUMERATION_RANGE(p->nProfileIndex,count);
30254272c0e474f97ac0269706170eb9161b36a9170wgu
30354272c0e474f97ac0269706170eb9161b36a9170wgu    p->eProfile = plTable[p->nProfileIndex].profile;
30454272c0e474f97ac0269706170eb9161b36a9170wgu    p->eLevel = plTable[p->nProfileIndex].level;
3056bc8d027bb46c0638d26b3f755350b84f6325de3wfeng
3066bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    return OMX_ErrorNone;
3076bc8d027bb46c0638d26b3f755350b84f6325de3wfeng}
3086bc8d027bb46c0638d26b3f755350b84f6325de3wfeng
3090541f11be2f78b558476772f1f877e140f9d844bywanOMX_ERRORTYPE OMXVideoDecoderAVC::SetParamVideoAVCProfileLevel(OMX_PTR) {
3106bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    LOGW("SetParamVideoAVCProfileLevel is not supported.");
3116bc8d027bb46c0638d26b3f755350b84f6325de3wfeng    return OMX_ErrorUnsupportedSetting;
3126bc8d027bb46c0638d26b3f755350b84f6325de3wfeng}
313e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu
3140541f11be2f78b558476772f1f877e140f9d844bywanOMX_COLOR_FORMATTYPE OMXVideoDecoderAVC::GetOutputColorFormat(int width)
31573cebb604e43c066d2d31eb145f82fc3080db532wfeng{
31673cebb604e43c066d2d31eb145f82fc3080db532wfeng#ifdef USE_GEN_HW
31773cebb604e43c066d2d31eb145f82fc3080db532wfeng    return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled;
31873cebb604e43c066d2d31eb145f82fc3080db532wfeng#else
3190541f11be2f78b558476772f1f877e140f9d844bywan    return OMXVideoDecoderBase::GetOutputColorFormat(width);
32073cebb604e43c066d2d31eb145f82fc3080db532wfeng#endif
32173cebb604e43c066d2d31eb145f82fc3080db532wfeng}
32273cebb604e43c066d2d31eb145f82fc3080db532wfeng
32303118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi ChenOMX_ERRORTYPE OMXVideoDecoderAVC::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *p) {
32403118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen    OMX_ERRORTYPE ret;
32503118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen    CHECK_TYPE_HEADER(p);
32603118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen    CHECK_PORT_INDEX(p, OUTPORT_INDEX);
32703118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen
32803118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen    p->nBufferCountActual = MAX_OUTPORT_BUFFER_COUNT;
32903118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen    return OMXVideoDecoderBase::SetMaxOutputBufferCount(p);
33003118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen}
33103118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen
33211c1c17fed35585f9256031ee70db1c6c18d0219Yuanjun HuangDECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.AVC", "video_decoder.avc", OMXVideoDecoderAVC);
333