VideoEditorVideoDecoder.cpp revision 3b25fdc4a33b53cfcf67315c2d42ad699b8cefe2
15af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt/*
25af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * Copyright (C) 2011 NXP Software
35af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * Copyright (C) 2011 The Android Open Source Project
45af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *
55af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License");
65af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * you may not use this file except in compliance with the License.
75af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * You may obtain a copy of the License at
85af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *
95af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *      http://www.apache.org/licenses/LICENSE-2.0
105af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *
115af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * Unless required by applicable law or agreed to in writing, software
125af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS,
135af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * See the License for the specific language governing permissions and
155af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * limitations under the License.
165af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt */
175af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt/**
185af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt*************************************************************************
195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt* @file   VideoEditorVideoDecoder.cpp
20ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly* @brief  StageFright shell video decoder
215af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt*************************************************************************
225af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt*/
235af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#define LOG_NDEBUG 1
24ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#define LOG_TAG "VIDEOEDITOR_VIDEODECODER"
255af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt/*******************
265af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *     HEADERS     *
275af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *******************/
285af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
295af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include "VideoEditorVideoDecoder_internal.h"
305af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include "VideoEditorUtils.h"
3184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt#include "M4VD_Tools.h"
3284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
33a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root#include <media/stagefright/MetaData.h>
34a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root#include <media/stagefright/MediaDefs.h>
35a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root
365af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt/********************
375af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *   DEFINITIONS    *
38389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt ********************/
3978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff#define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00
40fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt#define MAX_DEC_BUFFERS 10
415af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt/********************
435af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt *   SOURCE CLASS   *
4478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff ********************/
4578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriffusing namespace android;
465af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
475af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtclass VideoEditorVideoDecoderSource : public MediaSource {
4884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    public:
4984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        VideoEditorVideoDecoderSource(const sp<MetaData> &format,
5084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt            VIDEOEDITOR_CodecType codecType, void *decoderShellContext);
5184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        virtual status_t start(MetaData *params = NULL);
525af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        virtual status_t stop();
535af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        virtual sp<MetaData> getFormat();
545af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        virtual status_t read(
5584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt            MediaBuffer **buffer, const ReadOptions *options = NULL);
5684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
5784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    protected :
5884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        virtual ~VideoEditorVideoDecoderSource();
59666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
60389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    private:
61389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        sp<MetaData> mFormat;
62389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        MediaBuffer* mBuffer;
636665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        MediaBufferGroup* mGroup;
6484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        Mutex mLock;
6584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        VideoEditorVideoDecoder_Context* mpDecShellContext;
66fbd11c41aeb535723b78a61087fb436e64891055jmzhu        int32_t mMaxAUSize;
67fbd11c41aeb535723b78a61087fb436e64891055jmzhu        bool mStarted;
6884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        VIDEOEDITOR_CodecType mCodecType;
6984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        VideoEditorVideoDecoderSource(const MediaSource &);
706665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        VideoEditorVideoDecoderSource &operator=(const MediaSource &);
716665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt};
7284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
7384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry ShmidtVideoEditorVideoDecoderSource::VideoEditorVideoDecoderSource(
7484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        const sp<MetaData> &format, VIDEOEDITOR_CodecType codecType,
7584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        void *decoderShellContext) :
7684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        mFormat(format),
77fbd11c41aeb535723b78a61087fb436e64891055jmzhu        mBuffer(NULL),
7884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        mGroup(NULL),
79fbd11c41aeb535723b78a61087fb436e64891055jmzhu        mStarted(false),
80fbd11c41aeb535723b78a61087fb436e64891055jmzhu        mCodecType(codecType) {
81fbd11c41aeb535723b78a61087fb436e64891055jmzhu    mpDecShellContext = (VideoEditorVideoDecoder_Context*) decoderShellContext;
82fbd11c41aeb535723b78a61087fb436e64891055jmzhu}
83fbd11c41aeb535723b78a61087fb436e64891055jmzhu
8484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry ShmidtVideoEditorVideoDecoderSource::~VideoEditorVideoDecoderSource() {
85c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    if (mStarted == true) {
86fbd11c41aeb535723b78a61087fb436e64891055jmzhu        stop();
87fbd11c41aeb535723b78a61087fb436e64891055jmzhu    }
886665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt}
896665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
906665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidtstatus_t VideoEditorVideoDecoderSource::start(
91fbd11c41aeb535723b78a61087fb436e64891055jmzhu        MetaData *params) {
92fbd11c41aeb535723b78a61087fb436e64891055jmzhu
93fbd11c41aeb535723b78a61087fb436e64891055jmzhu    LOGV("VideoEditorVideoDecoderSource::start() begin ");
94fbd11c41aeb535723b78a61087fb436e64891055jmzhu    if (!mStarted) {
95fbd11c41aeb535723b78a61087fb436e64891055jmzhu        if(mFormat->findInt32(kKeyMaxInputSize, &mMaxAUSize) == false) {
96fbd11c41aeb535723b78a61087fb436e64891055jmzhu            LOGW("FATAL: Should never happen ");
97fbd11c41aeb535723b78a61087fb436e64891055jmzhu            mMaxAUSize = 10000;
98fbd11c41aeb535723b78a61087fb436e64891055jmzhu        }
99fbd11c41aeb535723b78a61087fb436e64891055jmzhu
100fbd11c41aeb535723b78a61087fb436e64891055jmzhu        mGroup = new MediaBufferGroup;
101fbd11c41aeb535723b78a61087fb436e64891055jmzhu        if(mGroup == NULL) {
102fbd11c41aeb535723b78a61087fb436e64891055jmzhu            LOGE("FATAL: memory limitation ! ");
103fbd11c41aeb535723b78a61087fb436e64891055jmzhu            return NO_MEMORY;
104fbd11c41aeb535723b78a61087fb436e64891055jmzhu        }
105fbd11c41aeb535723b78a61087fb436e64891055jmzhu        LOGV("VideoEditorVideoDecoderSource:adding buffer to group MaxSize= %d",
1066665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt            mMaxAUSize);
107666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt        mGroup->add_buffer(new MediaBuffer(mMaxAUSize));
1086665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
1096665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        mStarted = true;
110666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt    }
1116665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    LOGV("VideoEditorVideoDecoderSource::start() end OK");
112fbd11c41aeb535723b78a61087fb436e64891055jmzhu    return OK;
113fbd11c41aeb535723b78a61087fb436e64891055jmzhu}
1146665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
115389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidtstatus_t VideoEditorVideoDecoderSource::stop() {
1166665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int ref_count = 0;
1176665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    int i;
1186665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
1196665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    LOGV("VideoEditorVideoDecoderSource::stop() begin");
1206665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    if (mStarted) {
121c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        if(mBuffer != NULL) {
122a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt            ref_count = mBuffer->refcount();
123c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt            LOGV("MediaBuffer refcount is %d",ref_count);
124c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt            for (i=0; i< ref_count; i++) {
125c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt                mBuffer->release();
1267b984e3f7e724f8a3547a707210319f3d479f261Steve Block            }
127c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
128c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt            mBuffer = NULL;
1296665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        }
1306665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        delete mGroup;
1316665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        mGroup = NULL;
132389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        mStarted = false;
133389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    }
134389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    LOGV("VideoEditorVideoDecoderSource::stop() end");
135389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    return OK;
136389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt}
137389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
138389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidtsp<MetaData> VideoEditorVideoDecoderSource::getFormat() {
139389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    Mutex::Autolock autolock(mLock);
140389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
141a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt    return mFormat;
1427b984e3f7e724f8a3547a707210319f3d479f261Steve Block}
143c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
144c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidtstatus_t VideoEditorVideoDecoderSource::read(MediaBuffer** buffer_out,
145c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        const ReadOptions *options) {
146c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
1476665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    Mutex::Autolock autolock(mLock);
148c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    //We donot use read options on decoder hence dont impliment this option here
149c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    M4_AccessUnit* pAccessUnit = mpDecShellContext->m_pNextAccessUnitToDecode;
150a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt    M4OSA_UInt32 lSize = 0;
151c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    M4OSA_ERR lerr = M4NO_ERROR;
152c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    int64_t frameTime;
153c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
1547b984e3f7e724f8a3547a707210319f3d479f261Steve Block    *buffer_out = NULL;
155c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt
156c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    LOGV("VideoEditorVideoDecoderSource::read begin");
1576665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt
158389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    if (options) {
159389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        int64_t time = 0;
160389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        ReadOptions::SeekMode mode = ReadOptions::SEEK_CLOSEST_SYNC;
161389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        bool hasOptions = FALSE;
162389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        hasOptions = options->getSeekTo(&time, &mode);
163389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        if (hasOptions) {
164389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt            LOGV("VideoEditorVideoDecoderSource: Options is not NULL  %lld %d",
165389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt                time, mode);
1666665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        } else {
1677b984e3f7e724f8a3547a707210319f3d479f261Steve Block            LOGV("VideoEditorVideoDecoderSource: Options is not NULL ****");
168c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt        }
169c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    }
170c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt    lerr = mGroup->acquire_buffer(&mBuffer);
1715af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (lerr != OK) {
1725af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        return lerr;
1736665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    }
1745af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    LOGV("VideoEditorVideoDecoderSource: got a buffer from group");
1755af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
1765af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    if (mStarted) {
177a165913421c5bed00a1f0b8e79e35e55b82aebbeDmitry Shmidt        //getNext AU from reader.
1785af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        lerr = mpDecShellContext->m_pReader->m_pFctGetNextAu(
17984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                   mpDecShellContext->m_pReader->m_readerContext,
180c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt                   (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler,
18184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                   pAccessUnit);
18284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        if (lerr == M4WAR_NO_DATA_YET) {
183389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt            LOGV("VideoEditorVideoDecoderSource::read() M4WAR_NO_DATA_YET");
184389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt            mBuffer->set_range(0, 0);
1855af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            mBuffer->meta_data()->clear();
1865af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
1875af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            *buffer_out = mBuffer;
1885af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        }
1895af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        if (lerr == M4WAR_NO_MORE_AU) {
190389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt            LOGV("VideoEditorVideoDecoderSource::read() returning err = "
19101e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt                "ERROR_END_OF_STREAM;");
19278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff            *buffer_out = NULL;
19301e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt            return ERROR_END_OF_STREAM;
19478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff        }
19501e182f704b07d0763c0906ab3b706bcf6928896Dmitry Shmidt        LOGV("VideoEditorVideoDecoderSource: getNextAU  succesful ts = %lf",
196389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt            pAccessUnit->m_CTS);
197389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
198389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        //copy the reader AU buffer to mBuffer
199389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt        lSize  = (pAccessUnit->m_size > (M4OSA_UInt32)mMaxAUSize)\
2005af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            ? (M4OSA_UInt32)mMaxAUSize : pAccessUnit->m_size;
2016665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt        LOGV("VideoDecoderSource:Read() copying AU to i/p buffer of decoder,"
2026665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt            "Bufer Add = 0x%x, size = %d", mBuffer->data(), lSize);
20384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        memcpy((void *)mBuffer->data(),(void *)pAccessUnit->m_dataAddress,
204c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidt            lSize);
20584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
20684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        mBuffer->set_range(0, lSize);
20784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        mBuffer->meta_data()->clear();
2087b984e3f7e724f8a3547a707210319f3d479f261Steve Block        frameTime = (int64_t)pAccessUnit->m_CTS;
2093df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt        mBuffer->meta_data()->setInt64(kKeyTime, (int64_t)frameTime*1000);
21084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
2115af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        // Replace the AU start code for H264
21284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        if (VIDEOEDITOR_kH264VideoDec == mCodecType) {
2135af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            uint8_t *data =(uint8_t *)mBuffer->data() + mBuffer->range_offset();
2145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            data[0]=0;
2155af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            data[1]=0;
2165af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            data[2]=0;
2176665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt            data[3]=1;
21884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        }
2195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        mBuffer->meta_data()->setInt32(kKeyIsSyncFrame,
2205af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt            (pAccessUnit->m_attribute == 0x04)? 1 : 0);
2215af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt        *buffer_out = mBuffer;
2225af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    }
223389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    LOGV("VideoEditorVideoDecoderSource::read end");
224389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt    return OK;
2257b984e3f7e724f8a3547a707210319f3d479f261Steve Block}
226389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt/********************
227389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt *      TOOLS       *
228389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt ********************/
22984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
230c3539e22bd7a59a12542b9ad961f7d7f0db9a8dfDmitry Shmidtstatic M4OSA_UInt32 VideoEditorVideoDecoder_GetBitsFromMemory(
23184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        VIDEOEDITOR_VIDEO_Bitstream_ctxt* parsingCtxt, M4OSA_UInt32 nb_bits) {
23284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    return (M4VD_Tools_GetBitsFromMemory((M4VS_Bitstream_ctxt*) parsingCtxt,
2336665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt            nb_bits));
2346665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt}
2355af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2367b984e3f7e724f8a3547a707210319f3d479f261Steve BlockM4OSA_ERR VideoEditorVideoDecoder_internalParseVideoDSI(M4OSA_UInt8* pVol,
2373df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt        M4OSA_Int32 aVolSize, M4DECODER_MPEG4_DecoderConfigInfo* pDci,
23884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        M4DECODER_VideoSize* pVideoSize) {
2395af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
2405af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    VIDEOEDITOR_VIDEO_Bitstream_ctxt parsingCtxt;
2415af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    M4OSA_UInt32 code, j;
2425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    M4OSA_MemAddr8 start;
2435af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    M4OSA_UInt8 i;
2445af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt    M4OSA_UInt32 time_incr_length;
2457977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 vol_verid=0, b_hierarchy_type;
2467977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
2477977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    /* Parsing variables */
2487977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 video_object_layer_shape = 0;
2497977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 sprite_enable = 0;
2507977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 reduced_resolution_vop_enable = 0;
2517977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 scalability = 0;
2527977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 enhancement_type = 0;
2537977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 complexity_estimation_disable = 0;
2547977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 interlaced = 0;
2557977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 sprite_warping_points = 0;
2567977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    M4OSA_UInt8 sprite_brightness_change = 0;
25784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    M4OSA_UInt8 quant_precision = 0;
25884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
25984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    /* Fill the structure with default parameters */
26084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    pVideoSize->m_uiWidth      = 0;
2617977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    pVideoSize->m_uiHeight     = 0;
2627977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
2637977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    pDci->uiTimeScale          = 0;
2647977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    pDci->uiProfile            = 0;
2657977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    pDci->uiUseOfResynchMarker = 0;
2667977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    pDci->bDataPartition       = M4OSA_FALSE;
26784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    pDci->bUseOfRVLC           = M4OSA_FALSE;
2685af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt
269a2d7e3e7d6e3f163f06e522378c6e2bd5cee28f8Kenny Root    /* Reset the bitstream context */
27078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff    parsingCtxt.stream_byte = 0;
2716665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt    parsingCtxt.stream_index = 8;
27284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    parsingCtxt.in = (M4OSA_MemAddr8) pVol;
27384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
2747977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt    start = (M4OSA_MemAddr8) pVol;
27584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
27684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    /* Start parsing */
27784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt    while (parsingCtxt.in - start < aVolSize) {
2787977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt        code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8);
27984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt        if (code == 0) {
28084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt            code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8);
28184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt            if (code == 0) {
28284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt,8);
2836665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt                if (code == 1) {
2847977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                    /* start code found */
28578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                    code = VideoEditorVideoDecoder_GetBitsFromMemory(
28678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        &parsingCtxt, 8);
28778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
28878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                    /* ----- 0x20..0x2F : video_object_layer_start_code ----- */
28978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
29078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                    if ((code > 0x1F) && (code < 0x30)) {
29178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
29278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 1);
29378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
29478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 8);
29578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
29678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 1);
29778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        if (code == 1) {
29878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
29978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                &parsingCtxt, 4);
30078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            vol_verid = (M4OSA_UInt8)code;
30154b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
30278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                &parsingCtxt, 3);
30378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        }
30454b75b4e772ac77df141ab077be074bc1c098987Irfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
30578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 4);
30678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        if (code == 15) {
30778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
30878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                &parsingCtxt, 16);
30978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        }
31078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
31178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 1);
31278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        if (code == 1) {
31378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
31478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                &parsingCtxt, 3);
31578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
31678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                &parsingCtxt, 1);
31778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            if (code == 1) {
31878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
31978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 32);
32078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
32178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 31);
32278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
32378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 16);
32478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            }
32578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        }
32678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
32778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 2);
32878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        /* Need to save it for vop parsing */
32978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        video_object_layer_shape = (M4OSA_UInt8)code;
33078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
33178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        if (code != 0) {
33278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            return 0;    /* only rectangular case supported */
33378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        }
33478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
33578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
33678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 1);
33778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
33878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            &parsingCtxt, 16);
33978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        pDci->uiTimeScale = code;
34078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
34178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        /* Computes time increment length */
34278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        j    = code - 1;
3437977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        for (i = 0; (i < 32) && (j != 0); j >>=1) {
3447977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            i++;
3457977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        }
346321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt                        time_incr_length = (i == 0) ? 1 : i;
3477977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
348321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
3497977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            &parsingCtxt, 1);
350321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
3517977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            &parsingCtxt, 1);
3527977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        if (code == 1) {
3537977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
3547977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                &parsingCtxt, time_incr_length);
3557977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        }
3567977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
35778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                        if(video_object_layer_shape != 1) { /* 1 = Binary */
358321f95a95cd41e0f58a72ca4f382d7e0a7f26d01Dmitry Shmidt                            if(video_object_layer_shape == 0) {
3597977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
3607977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                    &parsingCtxt, 1);/* Marker bit */
3617977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
3627977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                    &parsingCtxt, 13);/* Width */
3637977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                pVideoSize->m_uiWidth = code;
3647977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
3657977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                    &parsingCtxt, 1);/* Marker bit */
3667977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
3677977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                    &parsingCtxt, 13);/* Height */
3687977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                pVideoSize->m_uiHeight = code;
3697977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
3707977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                                    &parsingCtxt, 1);/* Marker bit */
3717977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            }
3727977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        }
3737977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
3747977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
3757977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            &parsingCtxt, 1);/* interlaced */
3767977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        interlaced = (M4OSA_UInt8)code;
3777977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
3787977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            &parsingCtxt, 1);/* OBMC disable */
3797977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt
38084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                        if(vol_verid == 1) {
3817977d67059ef94eefa9b14038df156b416fef877Dmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
38284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                                &parsingCtxt, 1);/* sprite enable */
38384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                            sprite_enable = (M4OSA_UInt8)code;
3846665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt                        } else {
38584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
38684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                                &parsingCtxt, 2);/* sprite enable */
38784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                            sprite_enable = (M4OSA_UInt8)code;
38884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                        }
3897b984e3f7e724f8a3547a707210319f3d479f261Steve Block                        if ((sprite_enable == 1) || (sprite_enable == 2)) {
3903df450af1c2e35d854768a508b6905c6794f7a74Dmitry Shmidt                            if (sprite_enable != 2) {
39184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt
39278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
39384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt                                    &parsingCtxt, 13);/* sprite width */
3945af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
39531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                    &parsingCtxt, 1);/* Marker bit */
39678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
39778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 13);/* sprite height */
39878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
39978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 1);/* Marker bit */
40078dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
40178dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 13);/* sprite l coordinate */
40278dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
40378dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 1);/* Marker bit */
40478dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
40578dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 13);/* sprite top coordinate */
40678dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
40778dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                                    &parsingCtxt, 1);/* Marker bit */
40878dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff                            }
40978dcb76aff7d3b9458374832a79688d36901127fIrfan Sheriff
41031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
41131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                &parsingCtxt, 6);/* sprite warping points */
41231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            sprite_warping_points = (M4OSA_UInt8)code;
41331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
41431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                &parsingCtxt, 2);/* sprite warping accuracy */
41531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
41631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                &parsingCtxt, 1);/* sprite brightness change */
4176665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt                            sprite_brightness_change = (M4OSA_UInt8)code;
41831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            if (sprite_enable != 2) {
419fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
42031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                    &parsingCtxt, 1);
42131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            }
42231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                        }
42331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                        if ((vol_verid != 1) && (video_object_layer_shape != 0)){
42431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
42531fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            &parsingCtxt, 1);/* sadct disable */
42631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                        }
42731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt
42831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
42931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            &parsingCtxt, 1); /* not 8 bits */
43031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                        if (code) {
43131fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
43231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                &parsingCtxt, 4);/* quant precision */
433fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt                            quant_precision = (M4OSA_UInt8)code;
43454cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
43554cf7fda69c3c442e7d2ac370a9c942fdb38dcd7Dmitry Shmidt                                &parsingCtxt, 4);/* bits per pixel */
43631fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                        }
437fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt
43831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                        /* greyscale not supported */
439fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt                        if(video_object_layer_shape == 3) {
440fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
441389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt                                &parsingCtxt, 3);
442389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt                        }
443389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt
444fe15b63d9def3721bb0ee4d2fa36c6f4d0daf8aaDmitry Shmidt                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
4456665fb2adf78beddde21f7f3088a695646ca8c57Dmitry Shmidt                            &parsingCtxt, 1);/* quant type */
446389f8d1550880f3bc67ade3e93f2ddb767e64092Dmitry Shmidt                        if (code) {
44731fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
44831fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                &parsingCtxt, 1);/* load intra quant mat */
44931fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                            if (code) {
45031fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
4517b984e3f7e724f8a3547a707210319f3d479f261Steve Block                                    &parsingCtxt, 8);/* */
45231fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                i    = 1;
45331fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                while (i < 64) {
45431fd6c5f3e9c39a13b028718dba5921a4300988cDmitry Shmidt                                    code =
455666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                        VideoEditorVideoDecoder_GetBitsFromMemory(
456666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                            &parsingCtxt, 8);
457666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                    if (code == 0) {
458666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                        break;
459666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                    }
460666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                    i++;
461666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                }
462666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                            }
463666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt
464666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
465666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                &parsingCtxt, 1);/* load non intra quant mat */
466666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                            if (code) {
467666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
468666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                    &parsingCtxt, 8);/* */
469666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                i    = 1;
4707b984e3f7e724f8a3547a707210319f3d479f261Steve Block                                while (i < 64) {
471666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                    code =
472666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                        VideoEditorVideoDecoder_GetBitsFromMemory(
473666fe255fa581965d2835bd581cd5a8959411067Dmitry Shmidt                                        &parsingCtxt, 8);
474                                    if (code == 0) {
475                                        break;
476                                    }
477                                    i++;
478                                }
479                            }
480                        }
481
482                        if (vol_verid != 1) {
483                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
484                                &parsingCtxt, 1);/* quarter sample */
485                        }
486
487                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
488                            &parsingCtxt, 1);/* complexity estimation disable */
489                        complexity_estimation_disable = (M4OSA_UInt8)code;
490                        if (!code) {
491                            //return M4ERR_NOT_IMPLEMENTED;
492                        }
493
494                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
495                            &parsingCtxt, 1);/* resync marker disable */
496                        pDci->uiUseOfResynchMarker = (code) ? 0 : 1;
497
498                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
499                            &parsingCtxt, 1);/* data partitionned */
500                        pDci->bDataPartition = (code) ? M4OSA_TRUE : M4OSA_FALSE;
501                        if (code) {
502                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
503                                &parsingCtxt, 1);/* reversible VLC */
504                            pDci->bUseOfRVLC = (code) ? M4OSA_TRUE : M4OSA_FALSE;
505                        }
506
507                        if (vol_verid != 1) {
508                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
509                                &parsingCtxt, 1);/* newpred */
510                            if (code) {
511                                //return M4ERR_PARAMETER;
512                            }
513
514                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
515                                &parsingCtxt, 1);
516                            reduced_resolution_vop_enable = (M4OSA_UInt8)code;
517                        }
518
519                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
520                            &parsingCtxt, 1);/* scalability */
521                        scalability = (M4OSA_UInt8)code;
522                        if (code) {
523                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
524                                &parsingCtxt, 1);/* hierarchy type */
525                            b_hierarchy_type = (M4OSA_UInt8)code;
526                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
527                                &parsingCtxt, 4);/* ref layer id */
528                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
529                                &parsingCtxt, 1);/* ref sampling direct */
530                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
531                                &parsingCtxt, 5);/* hor sampling factor N */
532                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
533                                &parsingCtxt, 5);/* hor sampling factor M */
534                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
535                                &parsingCtxt, 5);/* vert sampling factor N */
536                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
537                                &parsingCtxt, 5);/* vert sampling factor M */
538                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
539                                &parsingCtxt, 1);/* enhancement type */
540                            enhancement_type = (M4OSA_UInt8)code;
541                            if ((!b_hierarchy_type) &&
542                                    (video_object_layer_shape == 1)) {
543                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
544                                    &parsingCtxt, 1);/* use ref shape */
545                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
546                                    &parsingCtxt, 1);/* use ref texture */
547                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
548                                    &parsingCtxt, 5);
549                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
550                                    &parsingCtxt, 5);
551                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
552                                    &parsingCtxt, 5);
553                                code = VideoEditorVideoDecoder_GetBitsFromMemory(
554                                    &parsingCtxt, 5);
555                            }
556                        }
557                        break;
558                    }
559
560                    /* ----- 0xB0 : visual_object_sequence_start_code ----- */
561
562                    else if(code == 0xB0) {
563                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
564                            &parsingCtxt, 8);/* profile_and_level_indication */
565                        pDci->uiProfile = (M4OSA_UInt8)code;
566                    }
567
568                    /* ----- 0xB5 : visual_object_start_code ----- */
569
570                    else if(code == 0xB5) {
571                        code = VideoEditorVideoDecoder_GetBitsFromMemory(
572                            &parsingCtxt, 1);/* is object layer identifier */
573                        if (code == 1) {
574                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
575                                &parsingCtxt, 4); /* visual object verid */
576                            vol_verid = (M4OSA_UInt8)code;
577                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
578                                &parsingCtxt, 3);
579                        } else {
580                            code = VideoEditorVideoDecoder_GetBitsFromMemory(
581                                &parsingCtxt, 7); /* Realign on byte */
582                            vol_verid = 1;
583                        }
584                    }
585
586                    /* ----- end ----- */
587                } else {
588                    if ((code >> 2) == 0x20) {
589                        /* H263 ...-> wrong*/
590                        break;
591                    }
592                }
593            }
594        }
595    }
596    return M4NO_ERROR;
597}
598
599M4VIFI_UInt8 M4VIFI_SemiplanarYVU420toYUV420(void *user_data,
600        M4VIFI_UInt8 *inyuv, M4VIFI_ImagePlane *PlaneOut ) {
601    M4VIFI_UInt8 return_code = M4VIFI_OK;
602    M4VIFI_UInt8 *outyuv =
603        ((M4VIFI_UInt8*)&(PlaneOut[0].pac_data[PlaneOut[0].u_topleft]));
604    int32_t width = PlaneOut[0].u_width;
605    int32_t height = PlaneOut[0].u_height;
606
607    int32_t outYsize = width * height;
608    uint32_t *outy =  (uint32_t *) outyuv;
609    uint16_t *outcb =
610        (uint16_t *) &(PlaneOut[1].pac_data[PlaneOut[1].u_topleft]);
611    uint16_t *outcr =
612        (uint16_t *) &(PlaneOut[2].pac_data[PlaneOut[2].u_topleft]);
613
614    /* Y copying */
615    memcpy((void *)outy, (void *)inyuv, outYsize);
616
617    /* U & V copying */
618    uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize);
619    for (int32_t i = height >> 1; i > 0; --i) {
620        for (int32_t j = width >> 2; j > 0; --j) {
621            uint32_t temp = *inyuv_4++;
622            uint32_t tempU = temp & 0xFF;
623            tempU = tempU | ((temp >> 8) & 0xFF00);
624
625            uint32_t tempV = (temp >> 8) & 0xFF;
626            tempV = tempV | ((temp >> 16) & 0xFF00);
627
628            // Flip U and V
629            *outcb++ = tempV;
630            *outcr++ = tempU;
631        }
632    }
633    return return_code;
634}
635
636M4OSA_ERR VideoEditorVideoDecoder_ParseAVCDSI(M4OSA_UInt8* pDSI,
637        M4OSA_Int32 DSISize, M4DECODER_AVCProfileLevel *profile) {
638    M4OSA_ERR err = M4NO_ERROR;
639    M4OSA_Bool NALSPS_and_Profile0Found = M4OSA_FALSE;
640    M4OSA_UInt16 index;
641    M4OSA_Bool constraintSet3;
642
643    for(index = 0; index < (DSISize-1); index++) {
644        if(((pDSI[index] & 0x1f) == 0x07) && (pDSI[index+1] == 0x42)) {
645            NALSPS_and_Profile0Found = M4OSA_TRUE;
646            break;
647        }
648    }
649    if(M4OSA_FALSE == NALSPS_and_Profile0Found) {
650        LOGV("VideoEditorVideoDecoder_ParseAVCDSI: index bad = %d", index);
651        *profile = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range;
652    } else {
653        LOGV("VideoEditorVideoDecoder_ParseAVCDSI: index = %d", index);
654        constraintSet3 = (pDSI[index+2] & 0x10);
655        LOGV("VideoEditorVideoDecoder_ParseAVCDSI: level = %d", pDSI[index+3]);
656        switch(pDSI[index+3]) {
657            case 10:
658                *profile = M4DECODER_AVC_kProfile_0_Level_1;
659                break;
660            case 11:
661                if(constraintSet3) {
662                    *profile = M4DECODER_AVC_kProfile_0_Level_1b;
663                } else {
664                    *profile = M4DECODER_AVC_kProfile_0_Level_1_1;
665                }
666                break;
667            case 12:
668                *profile = M4DECODER_AVC_kProfile_0_Level_1_2;
669                break;
670            case 13:
671                *profile = M4DECODER_AVC_kProfile_0_Level_1_3;
672                break;
673            case 20:
674                *profile = M4DECODER_AVC_kProfile_0_Level_2;
675                break;
676            case 21:
677                *profile = M4DECODER_AVC_kProfile_0_Level_2_1;
678                break;
679            case 22:
680                *profile = M4DECODER_AVC_kProfile_0_Level_2_2;
681                break;
682            case 30:
683                *profile = M4DECODER_AVC_kProfile_0_Level_3;
684                break;
685            case 31:
686                *profile = M4DECODER_AVC_kProfile_0_Level_3_1;
687                break;
688            case 32:
689                *profile = M4DECODER_AVC_kProfile_0_Level_3_2;
690                break;
691            case 40:
692                *profile = M4DECODER_AVC_kProfile_0_Level_4;
693                break;
694            case 41:
695                *profile = M4DECODER_AVC_kProfile_0_Level_4_1;
696                break;
697            case 42:
698                *profile = M4DECODER_AVC_kProfile_0_Level_4_2;
699                break;
700            case 50:
701                *profile = M4DECODER_AVC_kProfile_0_Level_5;
702                break;
703            case 51:
704                *profile = M4DECODER_AVC_kProfile_0_Level_5_1;
705                break;
706            default:
707                *profile = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range;
708        }
709    }
710    return err;
711}
712/********************
713 * ENGINE INTERFACE *
714 ********************/
715M4OSA_ERR VideoEditorVideoDecoder_configureFromMetadata(M4OSA_Context pContext,
716        MetaData* meta) {
717    M4OSA_ERR err = M4NO_ERROR;
718    VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL;
719    bool success = OK;
720    int32_t width = 0;
721    int32_t height = 0;
722    int32_t frameSize = 0;
723    int32_t vWidth, vHeight;
724    int32_t cropLeft, cropTop, cropRight, cropBottom;
725
726    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
727    VIDEOEDITOR_CHECK(M4OSA_NULL != meta,     M4ERR_PARAMETER);
728
729    LOGV("VideoEditorVideoDecoder_configureFromMetadata begin");
730
731    pDecShellContext = (VideoEditorVideoDecoder_Context*)pContext;
732
733    success = meta->findInt32(kKeyWidth, &vWidth);
734    VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
735    success = meta->findInt32(kKeyHeight, &vHeight);
736    VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
737
738    pDecShellContext->mGivenWidth = vWidth;
739    pDecShellContext->mGivenHeight = vHeight;
740
741    if (!meta->findRect(
742                kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
743
744        cropLeft = cropTop = 0;
745        cropRight = vWidth - 1;
746        cropBottom = vHeight - 1;
747
748        LOGV("got dimensions only %d x %d", width, height);
749    } else {
750        LOGV("got crop rect %d, %d, %d, %d",
751             cropLeft, cropTop, cropRight, cropBottom);
752    }
753
754    width = cropRight - cropLeft + 1;
755    height = cropBottom - cropTop + 1;
756
757    LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height);
758    VIDEOEDITOR_CHECK((0 != width) && (0 != height), M4ERR_PARAMETER);
759
760    LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height);
761
762    if( (M4OSA_NULL != pDecShellContext->m_pDecBufferPool) &&
763        (pDecShellContext->m_pVideoStreamhandler->m_videoWidth  == \
764            (uint32_t)width) &&
765        (pDecShellContext->m_pVideoStreamhandler->m_videoHeight == \
766            (uint32_t)height) ) {
767        // No need to reconfigure
768        goto cleanUp;
769    }
770    LOGV("VideoDecoder_configureFromMetadata  reset: W=%d H=%d", width, height);
771    // Update the stream handler parameters
772    pDecShellContext->m_pVideoStreamhandler->m_videoWidth  = width;
773    pDecShellContext->m_pVideoStreamhandler->m_videoHeight = height;
774    frameSize = (width * height * 3) / 2;
775
776    // Configure the buffer pool
777    if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) {
778        LOGV("VideoDecoder_configureFromMetadata : reset the buffer pool");
779        VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool);
780        pDecShellContext->m_pDecBufferPool = M4OSA_NULL;
781    }
782    err =  VIDEOEDITOR_BUFFER_allocatePool(&pDecShellContext->m_pDecBufferPool,
783        MAX_DEC_BUFFERS, (M4OSA_Char*)"VIDEOEDITOR_DecodedBufferPool");
784    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
785    err = VIDEOEDITOR_BUFFER_initPoolBuffers(pDecShellContext->m_pDecBufferPool,
786                frameSize + pDecShellContext->mGivenWidth * 2);
787
788    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
789
790cleanUp:
791    if( M4NO_ERROR == err ) {
792        LOGV("VideoEditorVideoDecoder_configureFromMetadata no error");
793    } else {
794        if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) {
795            VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool);
796            pDecShellContext->m_pDecBufferPool = M4OSA_NULL;
797        }
798        LOGV("VideoEditorVideoDecoder_configureFromMetadata ERROR 0x%X", err);
799    }
800    LOGV("VideoEditorVideoDecoder_configureFromMetadata end");
801    return err;
802}
803
804M4OSA_ERR VideoEditorVideoDecoder_destroy(M4OSA_Context pContext) {
805    M4OSA_ERR err = M4NO_ERROR;
806    VideoEditorVideoDecoder_Context* pDecShellContext =
807        (VideoEditorVideoDecoder_Context*)pContext;
808
809    // Input parameters check
810    LOGV("VideoEditorVideoDecoder_destroy begin");
811    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
812
813    // Destroy the graph
814    if( pDecShellContext->mVideoDecoder != NULL ) {
815        LOGV("### VideoEditorVideoDecoder_destroy : releasing decoder");
816        pDecShellContext->mVideoDecoder->stop();
817        pDecShellContext->mVideoDecoder.clear();
818    }
819    pDecShellContext->mClient.disconnect();
820    pDecShellContext->mReaderSource.clear();
821
822    // Release memory
823    if( pDecShellContext->m_pDecBufferPool != M4OSA_NULL ) {
824        VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool);
825        pDecShellContext->m_pDecBufferPool = M4OSA_NULL;
826    }
827    SAFE_FREE(pDecShellContext);
828    pContext = NULL;
829
830cleanUp:
831    if( M4NO_ERROR == err ) {
832        LOGV("VideoEditorVideoDecoder_destroy no error");
833    } else {
834        LOGV("VideoEditorVideoDecoder_destroy ERROR 0x%X", err);
835    }
836    LOGV("VideoEditorVideoDecoder_destroy end");
837    return err;
838}
839
840M4OSA_ERR VideoEditorVideoDecoder_create(M4OSA_Context *pContext,
841        M4_StreamHandler *pStreamHandler,
842        M4READER_DataInterface *pReaderDataInterface,
843        M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) {
844    M4OSA_ERR err = M4NO_ERROR;
845    VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL;
846    status_t status = OK;
847    bool success = TRUE;
848    int32_t colorFormat = 0;
849    M4OSA_UInt32 size = 0;
850    sp<MetaData> decoderMetadata = NULL;
851
852    LOGV("VideoEditorVideoDecoder_create begin");
853    // Input parameters check
854    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext,             M4ERR_PARAMETER);
855    VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler,       M4ERR_PARAMETER);
856    VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER);
857
858    // Context allocation & initialization
859    SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1,
860        "VideoEditorVideoDecoder");
861    pDecShellContext->m_pVideoStreamhandler =
862        (M4_VideoStreamHandler*)pStreamHandler;
863    pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit;
864    pDecShellContext->m_pReader = pReaderDataInterface;
865    pDecShellContext->m_lastDecodedCTS = -1;
866    pDecShellContext->m_lastRenderCts = -1;
867    switch( pStreamHandler->m_streamType ) {
868        case M4DA_StreamTypeVideoH263:
869            pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec;
870            break;
871        case M4DA_StreamTypeVideoMpeg4:
872            pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec;
873            // Parse the VOL header
874            err = VideoEditorVideoDecoder_internalParseVideoDSI(
875                (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\
876                    m_basicProperties.m_pDecoderSpecificInfo,
877                pDecShellContext->m_pVideoStreamhandler->\
878                    m_basicProperties.m_decoderSpecificInfoSize,
879                &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize);
880            VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
881            break;
882        case M4DA_StreamTypeVideoMpeg4Avc:
883            pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec;
884            break;
885        default:
886            VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
887                M4ERR_PARAMETER);
888            break;
889    }
890
891    pDecShellContext->mNbInputFrames     = 0;
892    pDecShellContext->mFirstInputCts     = -1.0;
893    pDecShellContext->mLastInputCts      = -1.0;
894    pDecShellContext->mNbRenderedFrames  = 0;
895    pDecShellContext->mFirstRenderedCts  = -1.0;
896    pDecShellContext->mLastRenderedCts   = -1.0;
897    pDecShellContext->mNbOutputFrames    = 0;
898    pDecShellContext->mFirstOutputCts    = -1;
899    pDecShellContext->mLastOutputCts     = -1;
900    pDecShellContext->m_pDecBufferPool   = M4OSA_NULL;
901
902    /**
903     * StageFright graph building
904     */
905    decoderMetadata = new MetaData;
906    switch( pDecShellContext->mDecoderType ) {
907        case VIDEOEDITOR_kH263VideoDec:
908            decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
909            break;
910        case VIDEOEDITOR_kMpeg4VideoDec:
911            decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
912            decoderMetadata->setData(kKeyESDS, kTypeESDS,
913                pStreamHandler->m_pESDSInfo,
914                pStreamHandler->m_ESDSInfoSize);
915            break;
916        case VIDEOEDITOR_kH264VideoDec:
917            decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
918            decoderMetadata->setData(kKeyAVCC, kTypeAVCC,
919                pStreamHandler->m_pH264DecoderSpecificInfo,
920                pStreamHandler->m_H264decoderSpecificInfoSize);
921            break;
922        default:
923            VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
924                M4ERR_PARAMETER);
925            break;
926    }
927
928    decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize);
929    decoderMetadata->setInt32(kKeyWidth,
930        pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
931    decoderMetadata->setInt32(kKeyHeight,
932        pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
933
934    // Create the decoder source
935    pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource(
936        decoderMetadata, pDecShellContext->mDecoderType,
937        (void *)pDecShellContext);
938    VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(),
939        M4ERR_SF_DECODER_RSRC_FAIL);
940
941    // Connect to the OMX client
942    status = pDecShellContext->mClient.connect();
943    VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
944
945    // Create the decoder
946    pDecShellContext->mVideoDecoder = OMXCodec::Create(
947        pDecShellContext->mClient.interface(),
948        decoderMetadata, false, pDecShellContext->mReaderSource);
949    VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(),
950        M4ERR_SF_DECODER_RSRC_FAIL);
951
952
953    // Get the output color format
954    success = pDecShellContext->mVideoDecoder->getFormat()->findInt32(
955        kKeyColorFormat, &colorFormat);
956    VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
957    pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
958
959    pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth,
960        pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
961    pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight,
962        pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
963
964    // Configure the buffer pool from the metadata
965    err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext,
966        pDecShellContext->mVideoDecoder->getFormat().get());
967    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
968
969    // Start the graph
970    status = pDecShellContext->mVideoDecoder->start();
971    VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
972
973    *pContext = (M4OSA_Context)pDecShellContext;
974
975cleanUp:
976    if( M4NO_ERROR == err ) {
977        LOGV("VideoEditorVideoDecoder_create no error");
978    } else {
979        VideoEditorVideoDecoder_destroy(pDecShellContext);
980        *pContext = M4OSA_NULL;
981        LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err);
982    }
983    LOGV("VideoEditorVideoDecoder_create : DONE");
984    return err;
985}
986
987M4OSA_ERR VideoEditorVideoSoftwareDecoder_create(M4OSA_Context *pContext,
988        M4_StreamHandler *pStreamHandler,
989        M4READER_DataInterface *pReaderDataInterface,
990        M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) {
991    M4OSA_ERR err = M4NO_ERROR;
992    VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL;
993    status_t status = OK;
994    bool success = TRUE;
995    int32_t colorFormat = 0;
996    M4OSA_UInt32 size = 0;
997    sp<MetaData> decoderMetadata = NULL;
998
999    LOGV("VideoEditorVideoDecoder_create begin");
1000    // Input parameters check
1001    VIDEOEDITOR_CHECK(M4OSA_NULL != pContext,             M4ERR_PARAMETER);
1002    VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler,       M4ERR_PARAMETER);
1003    VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER);
1004
1005    // Context allocation & initialization
1006    SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1,
1007        "VideoEditorVideoDecoder");
1008    pDecShellContext->m_pVideoStreamhandler =
1009        (M4_VideoStreamHandler*)pStreamHandler;
1010    pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit;
1011    pDecShellContext->m_pReader = pReaderDataInterface;
1012    pDecShellContext->m_lastDecodedCTS = -1;
1013    pDecShellContext->m_lastRenderCts = -1;
1014    switch( pStreamHandler->m_streamType ) {
1015        case M4DA_StreamTypeVideoH263:
1016            pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec;
1017            break;
1018        case M4DA_StreamTypeVideoMpeg4:
1019            pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec;
1020            // Parse the VOL header
1021            err = VideoEditorVideoDecoder_internalParseVideoDSI(
1022                (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\
1023                    m_basicProperties.m_pDecoderSpecificInfo,
1024                pDecShellContext->m_pVideoStreamhandler->\
1025                    m_basicProperties.m_decoderSpecificInfoSize,
1026                &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize);
1027            VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
1028            break;
1029        case M4DA_StreamTypeVideoMpeg4Avc:
1030            pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec;
1031            break;
1032        default:
1033            VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
1034                M4ERR_PARAMETER);
1035            break;
1036    }
1037
1038    pDecShellContext->mNbInputFrames     = 0;
1039    pDecShellContext->mFirstInputCts     = -1.0;
1040    pDecShellContext->mLastInputCts      = -1.0;
1041    pDecShellContext->mNbRenderedFrames  = 0;
1042    pDecShellContext->mFirstRenderedCts  = -1.0;
1043    pDecShellContext->mLastRenderedCts   = -1.0;
1044    pDecShellContext->mNbOutputFrames    = 0;
1045    pDecShellContext->mFirstOutputCts    = -1;
1046    pDecShellContext->mLastOutputCts     = -1;
1047    pDecShellContext->m_pDecBufferPool   = M4OSA_NULL;
1048
1049    /**
1050     * StageFright graph building
1051     */
1052    decoderMetadata = new MetaData;
1053    switch( pDecShellContext->mDecoderType ) {
1054        case VIDEOEDITOR_kH263VideoDec:
1055            decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
1056            break;
1057        case VIDEOEDITOR_kMpeg4VideoDec:
1058            decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
1059            decoderMetadata->setData(kKeyESDS, kTypeESDS,
1060                pStreamHandler->m_pESDSInfo,
1061                pStreamHandler->m_ESDSInfoSize);
1062            break;
1063        case VIDEOEDITOR_kH264VideoDec:
1064            decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
1065            decoderMetadata->setData(kKeyAVCC, kTypeAVCC,
1066                pStreamHandler->m_pH264DecoderSpecificInfo,
1067                pStreamHandler->m_H264decoderSpecificInfoSize);
1068            break;
1069        default:
1070            VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
1071                M4ERR_PARAMETER);
1072            break;
1073    }
1074
1075    decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize);
1076    decoderMetadata->setInt32(kKeyWidth,
1077        pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
1078    decoderMetadata->setInt32(kKeyHeight,
1079        pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
1080
1081    // Create the decoder source
1082    pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource(
1083        decoderMetadata, pDecShellContext->mDecoderType,
1084        (void *)pDecShellContext);
1085    VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(),
1086        M4ERR_SF_DECODER_RSRC_FAIL);
1087
1088    // Connect to the OMX client
1089    status = pDecShellContext->mClient.connect();
1090    VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
1091
1092     LOGI("Using software codecs only");
1093    // Create the decoder
1094    pDecShellContext->mVideoDecoder = OMXCodec::Create(
1095        pDecShellContext->mClient.interface(),
1096        decoderMetadata, false, pDecShellContext->mReaderSource,NULL,OMXCodec::kSoftwareCodecsOnly);
1097    VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(),
1098        M4ERR_SF_DECODER_RSRC_FAIL);
1099
1100    // Get the output color format
1101    success = pDecShellContext->mVideoDecoder->getFormat()->findInt32(
1102        kKeyColorFormat, &colorFormat);
1103    VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
1104    pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
1105
1106    pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth,
1107        pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
1108    pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight,
1109        pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
1110
1111    // Configure the buffer pool from the metadata
1112    err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext,
1113        pDecShellContext->mVideoDecoder->getFormat().get());
1114    VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
1115
1116    // Start the graph
1117    status = pDecShellContext->mVideoDecoder->start();
1118    VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
1119
1120    *pContext = (M4OSA_Context)pDecShellContext;
1121
1122cleanUp:
1123    if( M4NO_ERROR == err ) {
1124        LOGV("VideoEditorVideoDecoder_create no error");
1125    } else {
1126        VideoEditorVideoDecoder_destroy(pDecShellContext);
1127        *pContext = M4OSA_NULL;
1128        LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err);
1129    }
1130    LOGV("VideoEditorVideoDecoder_create : DONE");
1131    return err;
1132}
1133
1134
1135M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context,
1136        M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
1137    M4OSA_ERR lerr = M4NO_ERROR;
1138    VideoEditorVideoDecoder_Context* pDecShellContext =
1139        (VideoEditorVideoDecoder_Context*) context;
1140    M4_VersionInfo* pVersionInfo;
1141    M4DECODER_VideoSize* pVideoSize;
1142    M4OSA_UInt32* pNextFrameCts;
1143    M4OSA_UInt32 *plastDecodedFrameCts;
1144    M4DECODER_AVCProfileLevel* profile;
1145    M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo;
1146
1147    LOGV("VideoEditorVideoDecoder_getOption begin");
1148
1149    switch (optionId) {
1150        case M4DECODER_kOptionID_AVCLastDecodedFrameCTS:
1151             plastDecodedFrameCts = (M4OSA_UInt32 *) pValue;
1152             *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS;
1153             break;
1154
1155        case M4DECODER_kOptionID_Version:
1156            pVersionInfo = (M4_VersionInfo*)pValue;
1157
1158            pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR;
1159            pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR;
1160            pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION;
1161            pVersionInfo->m_structSize=sizeof(M4_VersionInfo);
1162            break;
1163
1164        case M4DECODER_kOptionID_VideoSize:
1165            /** Only VPS uses this Option ID. */
1166            pVideoSize = (M4DECODER_VideoSize*)pValue;
1167            pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth,
1168                (int32_t*)(&pVideoSize->m_uiWidth));
1169            pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight,
1170                (int32_t*)(&pVideoSize->m_uiHeight));
1171            LOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d",
1172                pVideoSize->m_uiWidth, pVideoSize->m_uiHeight);
1173            break;
1174
1175        case M4DECODER_kOptionID_NextRenderedFrameCTS:
1176            /** How to get this information. SF decoder does not provide this. *
1177            ** Let us provide last decoded frame CTS as of now. *
1178            ** Only VPS uses this Option ID. */
1179            pNextFrameCts = (M4OSA_UInt32 *)pValue;
1180            *pNextFrameCts = pDecShellContext->m_lastDecodedCTS;
1181            break;
1182        case M4DECODER_kOptionID_AVCProfileAndLevel:
1183            profile = (M4DECODER_AVCProfileLevel *) pValue;
1184            VideoEditorVideoDecoder_ParseAVCDSI (
1185                pDecShellContext->m_pVideoStreamhandler->\
1186                    m_basicProperties.m_pDecoderSpecificInfo,
1187                pDecShellContext->m_pVideoStreamhandler->\
1188                    m_basicProperties.m_decoderSpecificInfoSize,
1189                profile);
1190            break;
1191        case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo:
1192            if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) {
1193                (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) =
1194                    pDecShellContext->m_Dci;
1195            }
1196            break;
1197        default:
1198            lerr = M4ERR_BAD_OPTION_ID;
1199            break;
1200
1201    }
1202
1203    LOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr);
1204    return lerr;
1205}
1206
1207M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context,
1208        M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
1209    M4OSA_ERR lerr = M4NO_ERROR;
1210    VideoEditorVideoDecoder_Context *pDecShellContext =
1211        (VideoEditorVideoDecoder_Context*) context;
1212
1213    LOGV("VideoEditorVideoDecoder_setOption begin");
1214
1215    switch (optionId) {
1216        case M4DECODER_kOptionID_OutputFilter: {
1217                M4DECODER_OutputFilter* pOutputFilter =
1218                    (M4DECODER_OutputFilter*) pValue;
1219                pDecShellContext->m_pFilter =
1220                    (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\
1221                    m_pFilterFunction;
1222                pDecShellContext->m_pFilterUserData =
1223                    pOutputFilter->m_pFilterUserData;
1224            }
1225            break;
1226        case M4DECODER_kOptionID_DeblockingFilter:
1227            break;
1228        default:
1229            lerr = M4ERR_BAD_CONTEXT;
1230            break;
1231    }
1232
1233    LOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr);
1234    return lerr;
1235}
1236
1237M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context,
1238        M4_MediaTime* pTime, M4OSA_Bool bJump) {
1239    M4OSA_ERR lerr = M4NO_ERROR;
1240    VideoEditorVideoDecoder_Context* pDecShellContext =
1241        (VideoEditorVideoDecoder_Context*) context;
1242    int64_t lFrameTime;
1243    VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer;
1244    MediaSource::ReadOptions decShellOptions;
1245    MediaBuffer* pDecoderBuffer = NULL;
1246    status_t errStatus;
1247
1248
1249    LOGV("VideoEditorVideoDecoder_decode begin");
1250
1251    if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) {
1252        // Do not call read(), it could lead to a freeze
1253        LOGV("VideoEditorVideoDecoder_decode : EOS already reached");
1254        lerr = M4WAR_NO_MORE_AU;
1255        goto VIDEOEDITOR_VideoDecode_cleanUP;
1256    }
1257    if(pDecShellContext->m_lastDecodedCTS >= *pTime) {
1258        LOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.",
1259            pDecShellContext->m_lastDecodedCTS);
1260        goto VIDEOEDITOR_VideoDecode_cleanUP;
1261    }
1262    if(M4OSA_TRUE == bJump) {
1263        LOGV("VideoEditorVideoDecoder_decode: Jump called");
1264        pDecShellContext->m_lastDecodedCTS = -1;
1265        pDecShellContext->m_lastRenderCts = -1;
1266    }
1267
1268    pDecShellContext->mNbInputFrames++;
1269    if (0 > pDecShellContext->mFirstInputCts){
1270        pDecShellContext->mFirstInputCts = *pTime;
1271    }
1272    pDecShellContext->mLastInputCts = *pTime;
1273
1274    while (pDecShellContext->m_lastDecodedCTS < *pTime) {
1275        LOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf",
1276            pDecShellContext->m_lastDecodedCTS, *pTime);
1277        lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool,
1278            VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer);
1279        if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) {
1280            lerr = VIDEOEDITOR_BUFFER_getOldestBuffer(
1281                pDecShellContext->m_pDecBufferPool,
1282                VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer);
1283            tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty;
1284            lerr = M4NO_ERROR;
1285        }
1286
1287        if (lerr != M4NO_ERROR) {
1288            goto VIDEOEDITOR_VideoDecode_cleanUP;
1289        }
1290
1291        if (pDecoderBuffer != NULL) {
1292            pDecoderBuffer->release();
1293            pDecoderBuffer = NULL;
1294        }
1295
1296        decShellOptions.reset();
1297        errStatus = pDecShellContext->mVideoDecoder->read(&pDecoderBuffer,
1298            &decShellOptions);
1299        if (errStatus == ERROR_END_OF_STREAM) {
1300            LOGV("End of stream reached, returning M4WAR_NO_MORE_AU ");
1301            pDecShellContext->mReachedEOS = M4OSA_TRUE;
1302            lerr = M4WAR_NO_MORE_AU;
1303            goto VIDEOEDITOR_VideoDecode_cleanUP;
1304        } else if ( INFO_FORMAT_CHANGED == errStatus ) {
1305            LOGV("VideoDecoder_decode:source returns INFO_FORMAT_CHANGED:TODO");
1306
1307            LOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED");
1308            lerr = VideoEditorVideoDecoder_configureFromMetadata(
1309                pDecShellContext,
1310                pDecShellContext->mVideoDecoder->getFormat().get());
1311            if( M4NO_ERROR != lerr ) {
1312                LOGV("!!! VideoEditorVideoDecoder_decode ERROR : "
1313                    "VideoDecoder_configureFromMetadata returns 0x%X", lerr);
1314                break;
1315            }
1316            continue;
1317        }
1318
1319        if( 0 < pDecoderBuffer->range_length() ) {
1320        LOGV("VIDEOEDITOR_VideoDecoder frame buffer size = %d",
1321            pDecoderBuffer->range_length());
1322
1323        pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime);
1324        pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000);
1325        LOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d",
1326            (M4_MediaTime)lFrameTime, pDecoderBuffer->size() );
1327
1328        switch ( pDecShellContext->decOuputColorFormat ) {
1329            case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: {
1330                M4VIFI_ImagePlane tmpPlane[3];
1331                // Prepare the output image for conversion
1332                if( pDecoderBuffer->range_length() != (
1333                    pDecShellContext->m_pVideoStreamhandler->m_videoWidth *
1334                    pDecShellContext->m_pVideoStreamhandler->m_videoHeight \
1335                     * 3)/2 ) {
1336                    LOGV("VideoEditorVideoDecoder_decod invalid frame size S=%d"
1337                        "W=%d H=%d", pDecoderBuffer->range_length(),
1338                        pDecShellContext->m_pVideoStreamhandler->m_videoWidth,
1339                        pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
1340                    lerr = M4ERR_PARAMETER;
1341                    goto VIDEOEDITOR_VideoDecode_cleanUP;
1342                }
1343                tmpPlane[0].u_width   =
1344                    pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
1345                tmpPlane[0].u_height  =
1346                    pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
1347                tmpPlane[0].u_topleft = 0;
1348                tmpPlane[0].u_stride  = tmpPlane[0].u_width;
1349                tmpPlane[0].pac_data  = (M4VIFI_UInt8*)tmpDecBuffer->pData;
1350                tmpPlane[1].u_width   = tmpPlane[0].u_width/2;
1351                tmpPlane[1].u_height  = tmpPlane[0].u_height/2;
1352                tmpPlane[1].u_topleft = 0;
1353                tmpPlane[1].u_stride  = tmpPlane[0].u_stride/2;
1354                tmpPlane[1].pac_data  = tmpPlane[0].pac_data +
1355                    (tmpPlane[0].u_stride * tmpPlane[0].u_height);
1356                tmpPlane[2].u_width   = tmpPlane[1].u_width;
1357                tmpPlane[2].u_height  = tmpPlane[1].u_height;
1358                tmpPlane[2].u_topleft = 0;
1359                tmpPlane[2].u_stride  = tmpPlane[1].u_stride;
1360                tmpPlane[2].pac_data  = tmpPlane[1].pac_data +
1361                    (tmpPlane[1].u_stride * tmpPlane[1].u_height);
1362                M4VIFI_SemiplanarYVU420toYUV420(M4OSA_NULL,
1363                    (M4VIFI_UInt8 *)pDecoderBuffer->data() + \
1364                    pDecoderBuffer->range_offset(), &tmpPlane[0]);
1365                break;
1366            }
1367            case OMX_COLOR_FormatYUV420Planar:
1368            {
1369                int32_t width = pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
1370                int32_t height = pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
1371                int32_t yPlaneSize = width * height;
1372                int32_t uvPlaneSize = width * height / 4;
1373                int32_t offsetSrc = 0;
1374
1375                if (( width == pDecShellContext->mGivenWidth )  &&
1376                    ( height == pDecShellContext->mGivenHeight ))
1377                {
1378                    M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset();
1379
1380                    memcpy((void *)tmpDecBuffer->pData, (void *)pTmpBuff, yPlaneSize);
1381
1382                    offsetSrc += pDecShellContext->mGivenWidth * pDecShellContext->mGivenHeight;
1383                    memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize),
1384                        (void *)(pTmpBuff + offsetSrc), uvPlaneSize);
1385
1386                    offsetSrc += (pDecShellContext->mGivenWidth >> 1) * (pDecShellContext->mGivenHeight >> 1);
1387                    memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize + uvPlaneSize),
1388                        (void *)(pTmpBuff + offsetSrc), uvPlaneSize);
1389                }
1390                else
1391                {
1392                    M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset();
1393                    M4OSA_MemAddr8 pTmpBuffDst = (M4OSA_MemAddr8)tmpDecBuffer->pData;
1394                    int32_t index;
1395
1396                    for ( index = 0; index < height; index++)
1397                    {
1398                        memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width);
1399                        pTmpBuffDst += width;
1400                        pTmpBuff += pDecShellContext->mGivenWidth;
1401                    }
1402
1403                    pTmpBuff += (pDecShellContext->mGivenWidth * ( pDecShellContext->mGivenHeight - height));
1404                    for ( index = 0; index < height >> 1; index++)
1405                    {
1406                        memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1);
1407                        pTmpBuffDst += width >> 1;
1408                        pTmpBuff += pDecShellContext->mGivenWidth >> 1;
1409                    }
1410
1411                    pTmpBuff += ((pDecShellContext->mGivenWidth * (pDecShellContext->mGivenHeight - height)) / 4);
1412                    for ( index = 0; index < height >> 1; index++)
1413                    {
1414                        memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1);
1415                        pTmpBuffDst += width >> 1;
1416                        pTmpBuff += pDecShellContext->mGivenWidth >> 1;
1417                    }
1418                }
1419
1420                break;
1421            }
1422            default:
1423                LOGV("VideoDecoder_decode: unexpected color format 0x%X",
1424                    pDecShellContext->decOuputColorFormat);
1425                return M4ERR_PARAMETER;
1426        }
1427
1428        tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS;
1429        tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled;
1430        tmpDecBuffer->size = pDecoderBuffer->size();
1431
1432        } else {
1433            LOGV("VideoEditorVideoDecoder_decode : empty buffer was returned");
1434        }
1435    }
1436    pDecShellContext->mNbOutputFrames++;
1437    if ( 0 > pDecShellContext->mFirstOutputCts ) {
1438        pDecShellContext->mFirstOutputCts = *pTime;
1439    }
1440    pDecShellContext->mLastOutputCts = *pTime;
1441
1442VIDEOEDITOR_VideoDecode_cleanUP:
1443    *pTime = pDecShellContext->m_lastDecodedCTS;
1444    if (pDecoderBuffer != NULL) {
1445        pDecoderBuffer->release();
1446        pDecoderBuffer = NULL;
1447    }
1448
1449    LOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr);
1450    return lerr;
1451}
1452
1453M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context,
1454        M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane,
1455        M4OSA_Bool bForceRender) {
1456    M4OSA_ERR err = M4NO_ERROR;
1457    VideoEditorVideoDecoder_Context* pDecShellContext =
1458        (VideoEditorVideoDecoder_Context*) context;
1459    M4OSA_UInt32 lindex, i;
1460    M4OSA_UInt8* p_buf_src, *p_buf_dest;
1461    M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut;
1462    VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer
1463                                                                  = M4OSA_NULL;
1464    M4_MediaTime candidateTimeStamp = -1;
1465    M4OSA_Bool bFound = M4OSA_FALSE;
1466
1467    LOGV("VideoEditorVideoDecoder_render begin");
1468    // Input parameters check
1469    VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER);
1470    VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER);
1471    VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER);
1472
1473    // The output buffer is already allocated, just copy the data
1474    if ( (*pTime <= pDecShellContext->m_lastRenderCts) &&
1475            (M4OSA_FALSE == bForceRender) ) {
1476        LOGV("VIDEOEDITOR_VIDEO_render Frame in the past");
1477        err = M4WAR_VIDEORENDERER_NO_NEW_FRAME;
1478        goto cleanUp;
1479    }
1480    LOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = "
1481        "%lf", pDecShellContext->m_lastRenderCts, *pTime);
1482
1483    /**
1484     * Find the buffer appropriate for rendering.  */
1485    for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) {
1486        pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\
1487            ->pNXPBuffer[i];
1488        if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) {
1489            /** Free all those buffers older than last rendered frame. */
1490            if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\
1491                    m_lastRenderCts) {
1492                pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty;
1493            }
1494
1495            /** Get the buffer with appropriate timestamp  */
1496            if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\
1497                    m_lastRenderCts) &&
1498                (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) &&
1499                (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) {
1500                bFound = M4OSA_TRUE;
1501                pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer;
1502                candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS;
1503                LOGV("VideoDecoder_render: found a buffer with timestamp = %lf",
1504                    candidateTimeStamp);
1505            }
1506        }
1507    }
1508    if (M4OSA_FALSE == bFound) {
1509        err = M4WAR_VIDEORENDERER_NO_NEW_FRAME;
1510        goto cleanUp;
1511    }
1512
1513    LOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d",
1514        pOutputPlane[0].u_width, pOutputPlane[0].u_height,
1515        pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride);
1516
1517    pDecShellContext->m_lastRenderCts = candidateTimeStamp;
1518
1519    if( M4OSA_NULL != pDecShellContext->m_pFilter ) {
1520        // Filtering was requested
1521        M4VIFI_ImagePlane tmpPlane[3];
1522        // Prepare the output image for conversion
1523        tmpPlane[0].u_width   =
1524            pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
1525        tmpPlane[0].u_height  =
1526            pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
1527        tmpPlane[0].u_topleft = 0;
1528        tmpPlane[0].u_stride  = tmpPlane[0].u_width;
1529        tmpPlane[0].pac_data  = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData;
1530        tmpPlane[1].u_width   = tmpPlane[0].u_width/2;
1531        tmpPlane[1].u_height  = tmpPlane[0].u_height/2;
1532        tmpPlane[1].u_topleft = 0;
1533        tmpPlane[1].u_stride  = tmpPlane[0].u_stride/2;
1534        tmpPlane[1].pac_data  = tmpPlane[0].pac_data +
1535            (tmpPlane[0].u_stride * tmpPlane[0].u_height);
1536        tmpPlane[2].u_width   = tmpPlane[1].u_width;
1537        tmpPlane[2].u_height  = tmpPlane[1].u_height;
1538        tmpPlane[2].u_topleft = 0;
1539        tmpPlane[2].u_stride  = tmpPlane[1].u_stride;
1540        tmpPlane[2].pac_data  = tmpPlane[1].pac_data +
1541            (tmpPlane[1].u_stride * tmpPlane[1].u_height);
1542
1543        LOGV("VideoEditorVideoDecoder_render w = %d H = %d",
1544            tmpPlane[0].u_width,tmpPlane[0].u_height);
1545        pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane);
1546    } else {
1547        // Just copy the YUV420P buffer
1548        M4OSA_MemAddr8 tempBuffPtr =
1549            (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData;
1550        M4OSA_UInt32 tempWidth =
1551            pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
1552        M4OSA_UInt32 tempHeight =
1553            pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
1554
1555        memcpy((void *) pOutputPlane[0].pac_data, (void *)tempBuffPtr,
1556            tempWidth * tempHeight);
1557        tempBuffPtr += (tempWidth * tempHeight);
1558        memcpy((void *) pOutputPlane[1].pac_data, (void *)tempBuffPtr,
1559            (tempWidth/2) * (tempHeight/2));
1560        tempBuffPtr += ((tempWidth/2) * (tempHeight/2));
1561        memcpy((void *) pOutputPlane[2].pac_data, (void *)tempBuffPtr,
1562            (tempWidth/2) * (tempHeight/2));
1563    }
1564
1565    pDecShellContext->mNbRenderedFrames++;
1566    if ( 0 > pDecShellContext->mFirstRenderedCts ) {
1567        pDecShellContext->mFirstRenderedCts = *pTime;
1568    }
1569    pDecShellContext->mLastRenderedCts = *pTime;
1570
1571cleanUp:
1572    if( M4NO_ERROR == err ) {
1573        *pTime = pDecShellContext->m_lastRenderCts;
1574        LOGV("VideoEditorVideoDecoder_render no error");
1575    } else {
1576        LOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err);
1577    }
1578    LOGV("VideoEditorVideoDecoder_render end");
1579    return err;
1580}
1581
1582M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType,
1583        M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
1584    M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL;
1585
1586    pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
1587        sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL,
1588        (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" );
1589    if (M4OSA_NULL == pDecoderInterface) {
1590        return M4ERR_ALLOC;
1591    }
1592
1593    *pDecoderType = decoderType;
1594
1595    pDecoderInterface->m_pFctCreate    = VideoEditorVideoDecoder_create;
1596    pDecoderInterface->m_pFctDestroy   = VideoEditorVideoDecoder_destroy;
1597    pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption;
1598    pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption;
1599    pDecoderInterface->m_pFctDecode    = VideoEditorVideoDecoder_decode;
1600    pDecoderInterface->m_pFctRender    = VideoEditorVideoDecoder_render;
1601
1602    *pDecInterface = (M4OSA_Context)pDecoderInterface;
1603    return M4NO_ERROR;
1604}
1605
1606M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_VideoType decoderType,
1607        M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
1608    M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL;
1609
1610    pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
1611        sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL,
1612        (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" );
1613    if (M4OSA_NULL == pDecoderInterface) {
1614        return M4ERR_ALLOC;
1615    }
1616
1617    *pDecoderType = decoderType;
1618
1619    pDecoderInterface->m_pFctCreate    = VideoEditorVideoSoftwareDecoder_create;
1620    pDecoderInterface->m_pFctDestroy   = VideoEditorVideoDecoder_destroy;
1621    pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption;
1622    pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption;
1623    pDecoderInterface->m_pFctDecode    = VideoEditorVideoDecoder_decode;
1624    pDecoderInterface->m_pFctRender    = VideoEditorVideoDecoder_render;
1625
1626    *pDecInterface = (M4OSA_Context)pDecoderInterface;
1627    return M4NO_ERROR;
1628}
1629extern "C" {
1630
1631M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4(
1632        M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
1633    return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4,
1634        pDecoderType, pDecInterface);
1635}
1636
1637M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264(
1638        M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
1639    return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC,
1640        pDecoderType, pDecInterface);
1641
1642}
1643
1644M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_MPEG4(
1645        M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
1646    return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeMPEG4,
1647        pDecoderType, pDecInterface);
1648}
1649
1650M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_H264(
1651        M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
1652    return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeAVC,
1653        pDecoderType, pDecInterface);
1654
1655}
1656
1657}  // extern "C"
1658