Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /**
     17 *************************************************************************
     18 * @file   VideoEditorVideoDecoder.cpp
     19 * @brief  StageFright shell video decoder
     20 *************************************************************************
     21 */
     22 #define LOG_NDEBUG 1
     23 #define LOG_TAG "VIDEOEDITOR_VIDEODECODER"
     24 /*******************
     25  *     HEADERS     *
     26  *******************/
     27 
     28 #include "VideoEditorVideoDecoder_internal.h"
     29 #include "VideoEditorUtils.h"
     30 #include "M4VD_Tools.h"
     31 
     32 #include <media/stagefright/foundation/ADebug.h>
     33 #include <media/stagefright/MetaData.h>
     34 #include <media/stagefright/MediaDefs.h>
     35 /********************
     36  *   DEFINITIONS    *
     37  ********************/
     38 #define MAX_DEC_BUFFERS 10
     39 
     40 /********************
     41  *   SOURCE CLASS   *
     42  ********************/
     43 using namespace android;
     44 static M4OSA_ERR copyBufferToQueue(
     45     VideoEditorVideoDecoder_Context* pDecShellContext,
     46     MediaBuffer* pDecodedBuffer);
     47 
     48 class VideoEditorVideoDecoderSource : public MediaSource {
     49     public:
     50 
     51         VideoEditorVideoDecoderSource(
     52             const sp<MetaData> &format,
     53             VIDEOEDITOR_CodecType codecType,
     54             void *decoderShellContext);
     55 
     56         virtual status_t start(MetaData *params = NULL);
     57         virtual status_t stop();
     58         virtual sp<MetaData> getFormat();
     59         virtual status_t read(
     60             MediaBuffer **buffer, const ReadOptions *options = NULL);
     61 
     62     protected :
     63         virtual ~VideoEditorVideoDecoderSource();
     64 
     65     private:
     66         sp<MetaData> mFormat;
     67         MediaBuffer* mBuffer;
     68         MediaBufferGroup* mGroup;
     69         Mutex mLock;
     70         VideoEditorVideoDecoder_Context* mpDecShellContext;
     71         int32_t mMaxAUSize;
     72         bool mStarted;
     73         VIDEOEDITOR_CodecType mCodecType;
     74 
     75         // Don't call me
     76         VideoEditorVideoDecoderSource(const VideoEditorVideoDecoderSource &);
     77         VideoEditorVideoDecoderSource &operator=(
     78             const VideoEditorVideoDecoderSource &);
     79 };
     80 
     81 VideoEditorVideoDecoderSource::VideoEditorVideoDecoderSource(
     82         const sp<MetaData> &format, VIDEOEDITOR_CodecType codecType,
     83         void *decoderShellContext) :
     84         mFormat(format),
     85         mBuffer(NULL),
     86         mGroup(NULL),
     87         mStarted(false),
     88         mCodecType(codecType) {
     89     mpDecShellContext = (VideoEditorVideoDecoder_Context*) decoderShellContext;
     90 }
     91 
     92 VideoEditorVideoDecoderSource::~VideoEditorVideoDecoderSource() {
     93     if (mStarted == true) {
     94         stop();
     95     }
     96 }
     97 
     98 status_t VideoEditorVideoDecoderSource::start(
     99         MetaData *params) {
    100 
    101     if (!mStarted) {
    102         if (mFormat->findInt32(kKeyMaxInputSize, &mMaxAUSize) == false) {
    103             ALOGE("Could not find kKeyMaxInputSize");
    104             return ERROR_MALFORMED;
    105         }
    106 
    107         mGroup = new MediaBufferGroup;
    108         if (mGroup == NULL) {
    109             ALOGE("FATAL: memory limitation ! ");
    110             return NO_MEMORY;
    111         }
    112 
    113         mGroup->add_buffer(new MediaBuffer(mMaxAUSize));
    114 
    115         mStarted = true;
    116     }
    117     return OK;
    118 }
    119 
    120 status_t VideoEditorVideoDecoderSource::stop() {
    121     if (mStarted) {
    122         if (mBuffer != NULL) {
    123 
    124             // FIXME:
    125             // Why do we need to check on the ref count?
    126             int ref_count = mBuffer->refcount();
    127             ALOGV("MediaBuffer refcount is %d",ref_count);
    128             for (int i = 0; i < ref_count; ++i) {
    129                 mBuffer->release();
    130             }
    131 
    132             mBuffer = NULL;
    133         }
    134         delete mGroup;
    135         mGroup = NULL;
    136         mStarted = false;
    137     }
    138     return OK;
    139 }
    140 
    141 sp<MetaData> VideoEditorVideoDecoderSource::getFormat() {
    142     Mutex::Autolock autolock(mLock);
    143 
    144     return mFormat;
    145 }
    146 
    147 status_t VideoEditorVideoDecoderSource::read(MediaBuffer** buffer_out,
    148         const ReadOptions *options) {
    149 
    150     Mutex::Autolock autolock(mLock);
    151     if (options != NULL) {
    152         int64_t time_us;
    153         MediaSource::ReadOptions::SeekMode mode;
    154         options->getSeekTo(&time_us, &mode);
    155         if (mode != MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC) {
    156             ALOGE("Unexpected read options");
    157             return BAD_VALUE;
    158         }
    159 
    160         M4OSA_ERR err;
    161         M4OSA_Int32 rapTime = time_us / 1000;
    162 
    163         /*--- Retrieve the previous RAP time ---*/
    164         err = mpDecShellContext->m_pReaderGlobal->m_pFctGetPrevRapTime(
    165                   mpDecShellContext->m_pReader->m_readerContext,
    166                   (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler,
    167                   &rapTime);
    168 
    169         if (err == M4WAR_READER_INFORMATION_NOT_PRESENT) {
    170             /* No RAP table, jump backward and predecode */
    171             rapTime -= 40000;
    172             if(rapTime < 0) rapTime = 0;
    173         } else if (err != OK) {
    174             ALOGE("get rap time error = 0x%x\n", (uint32_t)err);
    175             return UNKNOWN_ERROR;
    176         }
    177 
    178         err = mpDecShellContext->m_pReaderGlobal->m_pFctJump(
    179                    mpDecShellContext->m_pReader->m_readerContext,
    180                    (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler,
    181                    &rapTime);
    182 
    183         if (err != OK) {
    184             ALOGE("jump err = 0x%x\n", (uint32_t)err);
    185             return BAD_VALUE;
    186         }
    187     }
    188 
    189     *buffer_out = NULL;
    190 
    191     M4OSA_ERR lerr = mGroup->acquire_buffer(&mBuffer);
    192     if (lerr != OK) {
    193         return lerr;
    194     }
    195     mBuffer->meta_data()->clear();  // clear all the meta data
    196 
    197     if (mStarted) {
    198         //getNext AU from reader.
    199         M4_AccessUnit* pAccessUnit = mpDecShellContext->m_pNextAccessUnitToDecode;
    200         lerr = mpDecShellContext->m_pReader->m_pFctGetNextAu(
    201                    mpDecShellContext->m_pReader->m_readerContext,
    202                    (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler,
    203                    pAccessUnit);
    204         if (lerr == M4WAR_NO_DATA_YET || lerr == M4WAR_NO_MORE_AU) {
    205             *buffer_out = NULL;
    206             return ERROR_END_OF_STREAM;
    207         }
    208 
    209         //copy the reader AU buffer to mBuffer
    210         M4OSA_UInt32 lSize  = (pAccessUnit->m_size > (M4OSA_UInt32)mMaxAUSize)\
    211             ? (M4OSA_UInt32)mMaxAUSize : pAccessUnit->m_size;
    212         memcpy((void *)mBuffer->data(),(void *)pAccessUnit->m_dataAddress,
    213             lSize);
    214 
    215         mBuffer->set_range(0, lSize);
    216         int64_t frameTimeUs = (int64_t) (pAccessUnit->m_CTS * 1000);
    217         mBuffer->meta_data()->setInt64(kKeyTime, frameTimeUs);
    218 
    219         // Replace the AU start code for H264
    220         if (VIDEOEDITOR_kH264VideoDec == mCodecType) {
    221             uint8_t *data =(uint8_t *)mBuffer->data() + mBuffer->range_offset();
    222             data[0]=0;
    223             data[1]=0;
    224             data[2]=0;
    225             data[3]=1;
    226         }
    227         mBuffer->meta_data()->setInt32(kKeyIsSyncFrame,
    228             (pAccessUnit->m_attribute == 0x04)? 1 : 0);
    229         *buffer_out = mBuffer;
    230     }
    231     return OK;
    232 }
    233 
    234 static M4OSA_UInt32 VideoEditorVideoDecoder_GetBitsFromMemory(
    235         VIDEOEDITOR_VIDEO_Bitstream_ctxt* parsingCtxt, M4OSA_UInt32 nb_bits) {
    236     return (M4VD_Tools_GetBitsFromMemory((M4VS_Bitstream_ctxt*) parsingCtxt,
    237             nb_bits));
    238 }
    239 
    240 M4OSA_ERR VideoEditorVideoDecoder_internalParseVideoDSI(M4OSA_UInt8* pVol,
    241         M4OSA_Int32 aVolSize, M4DECODER_MPEG4_DecoderConfigInfo* pDci,
    242         M4DECODER_VideoSize* pVideoSize) {
    243 
    244     VIDEOEDITOR_VIDEO_Bitstream_ctxt parsingCtxt;
    245     M4OSA_UInt32 code, j;
    246     M4OSA_MemAddr8 start;
    247     M4OSA_UInt8 i;
    248     M4OSA_UInt32 time_incr_length;
    249     M4OSA_UInt8 vol_verid=0, b_hierarchy_type;
    250 
    251     /* Parsing variables */
    252     M4OSA_UInt8 video_object_layer_shape = 0;
    253     M4OSA_UInt8 sprite_enable = 0;
    254     M4OSA_UInt8 reduced_resolution_vop_enable = 0;
    255     M4OSA_UInt8 scalability = 0;
    256     M4OSA_UInt8 enhancement_type = 0;
    257     M4OSA_UInt8 complexity_estimation_disable = 0;
    258     M4OSA_UInt8 interlaced = 0;
    259     M4OSA_UInt8 sprite_warping_points = 0;
    260     M4OSA_UInt8 sprite_brightness_change = 0;
    261     M4OSA_UInt8 quant_precision = 0;
    262 
    263     /* Fill the structure with default parameters */
    264     pVideoSize->m_uiWidth      = 0;
    265     pVideoSize->m_uiHeight     = 0;
    266 
    267     pDci->uiTimeScale          = 0;
    268     pDci->uiProfile            = 0;
    269     pDci->uiUseOfResynchMarker = 0;
    270     pDci->bDataPartition       = M4OSA_FALSE;
    271     pDci->bUseOfRVLC           = M4OSA_FALSE;
    272 
    273     /* Reset the bitstream context */
    274     parsingCtxt.stream_byte = 0;
    275     parsingCtxt.stream_index = 8;
    276     parsingCtxt.in = (M4OSA_MemAddr8) pVol;
    277 
    278     start = (M4OSA_MemAddr8) pVol;
    279 
    280     /* Start parsing */
    281     while (parsingCtxt.in - start < aVolSize) {
    282         code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8);
    283         if (code == 0) {
    284             code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8);
    285             if (code == 0) {
    286                 code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt,8);
    287                 if (code == 1) {
    288                     /* start code found */
    289                     code = VideoEditorVideoDecoder_GetBitsFromMemory(
    290                         &parsingCtxt, 8);
    291 
    292                     /* ----- 0x20..0x2F : video_object_layer_start_code ----- */
    293 
    294                     if ((code > 0x1F) && (code < 0x30)) {
    295                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    296                             &parsingCtxt, 1);
    297                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    298                             &parsingCtxt, 8);
    299                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    300                             &parsingCtxt, 1);
    301                         if (code == 1) {
    302                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    303                                 &parsingCtxt, 4);
    304                             vol_verid = (M4OSA_UInt8)code;
    305                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    306                                 &parsingCtxt, 3);
    307                         }
    308                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    309                             &parsingCtxt, 4);
    310                         if (code == 15) {
    311                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    312                                 &parsingCtxt, 16);
    313                         }
    314                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    315                             &parsingCtxt, 1);
    316                         if (code == 1) {
    317                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    318                                 &parsingCtxt, 3);
    319                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    320                                 &parsingCtxt, 1);
    321                             if (code == 1) {
    322                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    323                                     &parsingCtxt, 32);
    324                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    325                                     &parsingCtxt, 31);
    326                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    327                                     &parsingCtxt, 16);
    328                             }
    329                         }
    330                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    331                             &parsingCtxt, 2);
    332                         /* Need to save it for vop parsing */
    333                         video_object_layer_shape = (M4OSA_UInt8)code;
    334 
    335                         if (code != 0) {
    336                             return 0;    /* only rectangular case supported */
    337                         }
    338 
    339                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    340                             &parsingCtxt, 1);
    341                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    342                             &parsingCtxt, 16);
    343                         pDci->uiTimeScale = code;
    344 
    345                         /* Computes time increment length */
    346                         j    = code - 1;
    347                         for (i = 0; (i < 32) && (j != 0); j >>=1) {
    348                             i++;
    349                         }
    350                         time_incr_length = (i == 0) ? 1 : i;
    351 
    352                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    353                             &parsingCtxt, 1);
    354                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    355                             &parsingCtxt, 1);
    356                         if (code == 1) {
    357                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    358                                 &parsingCtxt, time_incr_length);
    359                         }
    360 
    361                         if(video_object_layer_shape != 1) { /* 1 = Binary */
    362                             if(video_object_layer_shape == 0) {
    363                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    364                                     &parsingCtxt, 1);/* Marker bit */
    365                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    366                                     &parsingCtxt, 13);/* Width */
    367                                 pVideoSize->m_uiWidth = code;
    368                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    369                                     &parsingCtxt, 1);/* Marker bit */
    370                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    371                                     &parsingCtxt, 13);/* Height */
    372                                 pVideoSize->m_uiHeight = code;
    373                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    374                                     &parsingCtxt, 1);/* Marker bit */
    375                             }
    376                         }
    377 
    378                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    379                             &parsingCtxt, 1);/* interlaced */
    380                         interlaced = (M4OSA_UInt8)code;
    381                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    382                             &parsingCtxt, 1);/* OBMC disable */
    383 
    384                         if(vol_verid == 1) {
    385                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    386                                 &parsingCtxt, 1);/* sprite enable */
    387                             sprite_enable = (M4OSA_UInt8)code;
    388                         } else {
    389                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    390                                 &parsingCtxt, 2);/* sprite enable */
    391                             sprite_enable = (M4OSA_UInt8)code;
    392                         }
    393                         if ((sprite_enable == 1) || (sprite_enable == 2)) {
    394                             if (sprite_enable != 2) {
    395 
    396                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    397                                     &parsingCtxt, 13);/* sprite width */
    398                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    399                                     &parsingCtxt, 1);/* Marker bit */
    400                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    401                                     &parsingCtxt, 13);/* sprite height */
    402                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    403                                     &parsingCtxt, 1);/* Marker bit */
    404                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    405                                     &parsingCtxt, 13);/* sprite l coordinate */
    406                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    407                                     &parsingCtxt, 1);/* Marker bit */
    408                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    409                                     &parsingCtxt, 13);/* sprite top coordinate */
    410                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    411                                     &parsingCtxt, 1);/* Marker bit */
    412                             }
    413 
    414                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    415                                 &parsingCtxt, 6);/* sprite warping points */
    416                             sprite_warping_points = (M4OSA_UInt8)code;
    417                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    418                                 &parsingCtxt, 2);/* sprite warping accuracy */
    419                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    420                                 &parsingCtxt, 1);/* sprite brightness change */
    421                             sprite_brightness_change = (M4OSA_UInt8)code;
    422                             if (sprite_enable != 2) {
    423                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    424                                     &parsingCtxt, 1);
    425                             }
    426                         }
    427                         if ((vol_verid != 1) && (video_object_layer_shape != 0)){
    428                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    429                             &parsingCtxt, 1);/* sadct disable */
    430                         }
    431 
    432                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    433                             &parsingCtxt, 1); /* not 8 bits */
    434                         if (code) {
    435                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    436                                 &parsingCtxt, 4);/* quant precision */
    437                             quant_precision = (M4OSA_UInt8)code;
    438                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    439                                 &parsingCtxt, 4);/* bits per pixel */
    440                         }
    441 
    442                         /* greyscale not supported */
    443                         if(video_object_layer_shape == 3) {
    444                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    445                                 &parsingCtxt, 3);
    446                         }
    447 
    448                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    449                             &parsingCtxt, 1);/* quant type */
    450                         if (code) {
    451                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    452                                 &parsingCtxt, 1);/* load intra quant mat */
    453                             if (code) {
    454                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    455                                     &parsingCtxt, 8);/* */
    456                                 i    = 1;
    457                                 while (i < 64) {
    458                                     code =
    459                                         VideoEditorVideoDecoder_GetBitsFromMemory(
    460                                             &parsingCtxt, 8);
    461                                     if (code == 0) {
    462                                         break;
    463                                     }
    464                                     i++;
    465                                 }
    466                             }
    467 
    468                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    469                                 &parsingCtxt, 1);/* load non intra quant mat */
    470                             if (code) {
    471                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    472                                     &parsingCtxt, 8);/* */
    473                                 i    = 1;
    474                                 while (i < 64) {
    475                                     code =
    476                                         VideoEditorVideoDecoder_GetBitsFromMemory(
    477                                         &parsingCtxt, 8);
    478                                     if (code == 0) {
    479                                         break;
    480                                     }
    481                                     i++;
    482                                 }
    483                             }
    484                         }
    485 
    486                         if (vol_verid != 1) {
    487                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    488                                 &parsingCtxt, 1);/* quarter sample */
    489                         }
    490 
    491                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    492                             &parsingCtxt, 1);/* complexity estimation disable */
    493                         complexity_estimation_disable = (M4OSA_UInt8)code;
    494                         if (!code) {
    495                             //return M4ERR_NOT_IMPLEMENTED;
    496                         }
    497 
    498                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    499                             &parsingCtxt, 1);/* resync marker disable */
    500                         pDci->uiUseOfResynchMarker = (code) ? 0 : 1;
    501 
    502                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    503                             &parsingCtxt, 1);/* data partitionned */
    504                         pDci->bDataPartition = (code) ? M4OSA_TRUE : M4OSA_FALSE;
    505                         if (code) {
    506                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    507                                 &parsingCtxt, 1);/* reversible VLC */
    508                             pDci->bUseOfRVLC = (code) ? M4OSA_TRUE : M4OSA_FALSE;
    509                         }
    510 
    511                         if (vol_verid != 1) {
    512                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    513                                 &parsingCtxt, 1);/* newpred */
    514                             if (code) {
    515                                 //return M4ERR_PARAMETER;
    516                             }
    517 
    518                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    519                                 &parsingCtxt, 1);
    520                             reduced_resolution_vop_enable = (M4OSA_UInt8)code;
    521                         }
    522 
    523                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    524                             &parsingCtxt, 1);/* scalability */
    525                         scalability = (M4OSA_UInt8)code;
    526                         if (code) {
    527                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    528                                 &parsingCtxt, 1);/* hierarchy type */
    529                             b_hierarchy_type = (M4OSA_UInt8)code;
    530                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    531                                 &parsingCtxt, 4);/* ref layer id */
    532                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    533                                 &parsingCtxt, 1);/* ref sampling direct */
    534                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    535                                 &parsingCtxt, 5);/* hor sampling factor N */
    536                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    537                                 &parsingCtxt, 5);/* hor sampling factor M */
    538                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    539                                 &parsingCtxt, 5);/* vert sampling factor N */
    540                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    541                                 &parsingCtxt, 5);/* vert sampling factor M */
    542                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    543                                 &parsingCtxt, 1);/* enhancement type */
    544                             enhancement_type = (M4OSA_UInt8)code;
    545                             if ((!b_hierarchy_type) &&
    546                                     (video_object_layer_shape == 1)) {
    547                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    548                                     &parsingCtxt, 1);/* use ref shape */
    549                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    550                                     &parsingCtxt, 1);/* use ref texture */
    551                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    552                                     &parsingCtxt, 5);
    553                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    554                                     &parsingCtxt, 5);
    555                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    556                                     &parsingCtxt, 5);
    557                                 code = VideoEditorVideoDecoder_GetBitsFromMemory(
    558                                     &parsingCtxt, 5);
    559                             }
    560                         }
    561                         break;
    562                     }
    563 
    564                     /* ----- 0xB0 : visual_object_sequence_start_code ----- */
    565 
    566                     else if(code == 0xB0) {
    567                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    568                             &parsingCtxt, 8);/* profile_and_level_indication */
    569                         pDci->uiProfile = (M4OSA_UInt8)code;
    570                     }
    571 
    572                     /* ----- 0xB5 : visual_object_start_code ----- */
    573 
    574                     else if(code == 0xB5) {
    575                         code = VideoEditorVideoDecoder_GetBitsFromMemory(
    576                             &parsingCtxt, 1);/* is object layer identifier */
    577                         if (code == 1) {
    578                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    579                                 &parsingCtxt, 4); /* visual object verid */
    580                             vol_verid = (M4OSA_UInt8)code;
    581                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    582                                 &parsingCtxt, 3);
    583                         } else {
    584                             code = VideoEditorVideoDecoder_GetBitsFromMemory(
    585                                 &parsingCtxt, 7); /* Realign on byte */
    586                             vol_verid = 1;
    587                         }
    588                     }
    589 
    590                     /* ----- end ----- */
    591                 } else {
    592                     if ((code >> 2) == 0x20) {
    593                         /* H263 ...-> wrong*/
    594                         break;
    595                     }
    596                 }
    597             }
    598         }
    599     }
    600     return M4NO_ERROR;
    601 }
    602 
    603 M4VIFI_UInt8 M4VIFI_SemiplanarYVU420toYUV420(void *user_data,
    604         M4VIFI_UInt8 *inyuv, M4VIFI_ImagePlane *PlaneOut ) {
    605     M4VIFI_UInt8 return_code = M4VIFI_OK;
    606     M4VIFI_UInt8 *outyuv =
    607         ((M4VIFI_UInt8*)&(PlaneOut[0].pac_data[PlaneOut[0].u_topleft]));
    608     int32_t width = PlaneOut[0].u_width;
    609     int32_t height = PlaneOut[0].u_height;
    610 
    611     int32_t outYsize = width * height;
    612     uint32_t *outy =  (uint32_t *) outyuv;
    613     uint16_t *outcb =
    614         (uint16_t *) &(PlaneOut[1].pac_data[PlaneOut[1].u_topleft]);
    615     uint16_t *outcr =
    616         (uint16_t *) &(PlaneOut[2].pac_data[PlaneOut[2].u_topleft]);
    617 
    618     /* Y copying */
    619     memcpy((void *)outy, (void *)inyuv, outYsize);
    620 
    621     /* U & V copying */
    622     uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize);
    623     for (int32_t i = height >> 1; i > 0; --i) {
    624         for (int32_t j = width >> 2; j > 0; --j) {
    625             uint32_t temp = *inyuv_4++;
    626             uint32_t tempU = temp & 0xFF;
    627             tempU = tempU | ((temp >> 8) & 0xFF00);
    628 
    629             uint32_t tempV = (temp >> 8) & 0xFF;
    630             tempV = tempV | ((temp >> 16) & 0xFF00);
    631 
    632             // Flip U and V
    633             *outcb++ = tempV;
    634             *outcr++ = tempU;
    635         }
    636     }
    637     return return_code;
    638 }
    639 void logSupportDecodersAndCapabilities(M4DECODER_VideoDecoders* decoders) {
    640     VideoDecoder *pDecoder;
    641     VideoComponentCapabilities *pOmxComponents = NULL;
    642     VideoProfileLevel *pProfileLevel = NULL;
    643     pDecoder = decoders->decoder;
    644     for (size_t i = 0; i< decoders->decoderNumber; i++) {
    645         ALOGV("Supported Codec[%d] :%d", i, pDecoder->codec);
    646         pOmxComponents = pDecoder->component;
    647         for(size_t j = 0; j <  pDecoder->componentNumber; j++) {
    648            pProfileLevel = pOmxComponents->profileLevel;
    649            ALOGV("-->component %d", j);
    650            for(size_t k = 0; k < pOmxComponents->profileNumber; k++) {
    651                ALOGV("-->profile:%ld maxLevel:%ld", pProfileLevel->mProfile,
    652                    pProfileLevel->mLevel);
    653                pProfileLevel++;
    654            }
    655            pOmxComponents++;
    656         }
    657         pDecoder++;
    658     }
    659 }
    660 
    661 M4OSA_ERR queryVideoDecoderCapabilities
    662     (M4DECODER_VideoDecoders** decoders) {
    663     M4OSA_ERR err = M4NO_ERROR;
    664     const char *kMimeTypes[] = {
    665         MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
    666         MEDIA_MIMETYPE_VIDEO_H263
    667     };
    668 
    669     int32_t supportFormats = sizeof(kMimeTypes) / sizeof(kMimeTypes[0]);
    670     M4DECODER_VideoDecoders *pDecoders;
    671     VideoDecoder *pDecoder;
    672     VideoComponentCapabilities *pOmxComponents = NULL;
    673     VideoProfileLevel *pProfileLevel = NULL;
    674     OMXClient client;
    675     status_t status = OK;
    676     SAFE_MALLOC(pDecoders, M4DECODER_VideoDecoders, 1, "VideoDecoders");
    677     SAFE_MALLOC(pDecoder, VideoDecoder, supportFormats,
    678         "VideoDecoder");
    679     pDecoders->decoder = pDecoder;
    680 
    681     pDecoders->decoderNumber= supportFormats;
    682     status = client.connect();
    683     CHECK(status == OK);
    684     for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]);
    685              ++k) {
    686             Vector<CodecCapabilities> results;
    687             CHECK_EQ(QueryCodecs(client.interface(), kMimeTypes[k],
    688                                  true, // queryDecoders
    689                                  &results), (status_t)OK);
    690 
    691             if (results.size()) {
    692                 SAFE_MALLOC(pOmxComponents, VideoComponentCapabilities,
    693                     results.size(), "VideoComponentCapabilities");
    694                 ALOGV("K=%d",k);
    695                 pDecoder->component = pOmxComponents;
    696                 pDecoder->componentNumber = results.size();
    697             }
    698 
    699             for (size_t i = 0; i < results.size(); ++i) {
    700                 ALOGV("  decoder '%s' supports ",
    701                        results[i].mComponentName.string());
    702 
    703                 if (results[i].mProfileLevels.size() == 0) {
    704                     ALOGV("NOTHING.\n");
    705                     continue;
    706                 }
    707 
    708 #if 0
    709                 // FIXME:
    710                 // We should ignore the software codecs and make IsSoftwareCodec()
    711                 // part of pubic API from OMXCodec.cpp
    712                 if (IsSoftwareCodec(results[i].mComponentName.string())) {
    713                     ALOGV("Ignore software codec %s", results[i].mComponentName.string());
    714                     continue;
    715                 }
    716 #endif
    717 
    718                 // Count the supported profiles
    719                 int32_t profileNumber = 0;
    720                 int32_t profile = -1;
    721                 for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) {
    722                     const CodecProfileLevel &profileLevel =
    723                         results[i].mProfileLevels[j];
    724                     // FIXME: assume that the profiles are ordered
    725                     if (profileLevel.mProfile != profile) {
    726                         profile = profileLevel.mProfile;
    727                         profileNumber++;
    728                     }
    729                 }
    730                 SAFE_MALLOC(pProfileLevel, VideoProfileLevel,
    731                     profileNumber, "VideoProfileLevel");
    732                 pOmxComponents->profileLevel = pProfileLevel;
    733                 pOmxComponents->profileNumber = profileNumber;
    734 
    735                 // Get the max Level for each profile.
    736                 int32_t maxLevel = -1;
    737                 profile = -1;
    738                 profileNumber = 0;
    739                 for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) {
    740                     const CodecProfileLevel &profileLevel =
    741                         results[i].mProfileLevels[j];
    742                     if (profile == -1 && maxLevel == -1) {
    743                         profile = profileLevel.mProfile;
    744                         maxLevel = profileLevel.mLevel;
    745                         pProfileLevel->mProfile = profile;
    746                         pProfileLevel->mLevel = maxLevel;
    747                         ALOGV("%d profile: %ld, max level: %ld",
    748                             __LINE__, pProfileLevel->mProfile, pProfileLevel->mLevel);
    749                     }
    750                     if (profileLevel.mProfile != profile) {
    751                         profile = profileLevel.mProfile;
    752                         maxLevel = profileLevel.mLevel;
    753                         profileNumber++;
    754                         pProfileLevel++;
    755                         pProfileLevel->mProfile = profile;
    756                         pProfileLevel->mLevel = maxLevel;
    757                         ALOGV("%d profile: %ld, max level: %ld",
    758                             __LINE__, pProfileLevel->mProfile, pProfileLevel->mLevel);
    759                     } else if (profileLevel.mLevel > maxLevel) {
    760                         maxLevel = profileLevel.mLevel;
    761                         pProfileLevel->mLevel = maxLevel;
    762                         ALOGV("%d profile: %ld, max level: %ld",
    763                             __LINE__, pProfileLevel->mProfile, pProfileLevel->mLevel);
    764                     }
    765 
    766                 }
    767                 pOmxComponents++;
    768             }
    769             if (!strcmp(MEDIA_MIMETYPE_VIDEO_AVC, kMimeTypes[k]))
    770                 pDecoder->codec = M4DA_StreamTypeVideoMpeg4Avc;
    771             if (!strcmp(MEDIA_MIMETYPE_VIDEO_MPEG4, kMimeTypes[k]))
    772                 pDecoder->codec = M4DA_StreamTypeVideoMpeg4;
    773             if (!strcmp(MEDIA_MIMETYPE_VIDEO_H263, kMimeTypes[k]))
    774                 pDecoder->codec = M4DA_StreamTypeVideoH263;
    775 
    776             pDecoder++;
    777     }
    778 
    779     logSupportDecodersAndCapabilities(pDecoders);
    780     *decoders = pDecoders;
    781 cleanUp:
    782     return err;
    783 }
    784 /********************
    785  * ENGINE INTERFACE *
    786  ********************/
    787 M4OSA_ERR VideoEditorVideoDecoder_configureFromMetadata(M4OSA_Context pContext,
    788         MetaData* meta) {
    789     M4OSA_ERR err = M4NO_ERROR;
    790     VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL;
    791     bool success = OK;
    792     int32_t width = 0;
    793     int32_t height = 0;
    794     int32_t frameSize = 0;
    795     int32_t vWidth, vHeight;
    796     int32_t cropLeft, cropTop, cropRight, cropBottom;
    797 
    798     VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
    799     VIDEOEDITOR_CHECK(M4OSA_NULL != meta,     M4ERR_PARAMETER);
    800 
    801     ALOGV("VideoEditorVideoDecoder_configureFromMetadata begin");
    802 
    803     pDecShellContext = (VideoEditorVideoDecoder_Context*)pContext;
    804 
    805     success = meta->findInt32(kKeyWidth, &vWidth);
    806     VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
    807     success = meta->findInt32(kKeyHeight, &vHeight);
    808     VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
    809 
    810     ALOGV("vWidth = %d, vHeight = %d", vWidth, vHeight);
    811 
    812     pDecShellContext->mGivenWidth = vWidth;
    813     pDecShellContext->mGivenHeight = vHeight;
    814 
    815     if (!meta->findRect(
    816                 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
    817 
    818         cropLeft = cropTop = 0;
    819         cropRight = vWidth - 1;
    820         cropBottom = vHeight - 1;
    821 
    822         ALOGV("got dimensions only %d x %d", width, height);
    823     } else {
    824         ALOGV("got crop rect %d, %d, %d, %d",
    825              cropLeft, cropTop, cropRight, cropBottom);
    826     }
    827 
    828     pDecShellContext->mCropRect.left = cropLeft;
    829     pDecShellContext->mCropRect.right = cropRight;
    830     pDecShellContext->mCropRect.top = cropTop;
    831     pDecShellContext->mCropRect.bottom = cropBottom;
    832 
    833     width = cropRight - cropLeft + 1;
    834     height = cropBottom - cropTop + 1;
    835 
    836     ALOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height);
    837     VIDEOEDITOR_CHECK((0 != width) && (0 != height), M4ERR_PARAMETER);
    838 
    839     if( (M4OSA_NULL != pDecShellContext->m_pDecBufferPool) &&
    840         (pDecShellContext->m_pVideoStreamhandler->m_videoWidth  == \
    841             (uint32_t)width) &&
    842         (pDecShellContext->m_pVideoStreamhandler->m_videoHeight == \
    843             (uint32_t)height) ) {
    844         // No need to reconfigure
    845         goto cleanUp;
    846     }
    847     ALOGV("VideoDecoder_configureFromMetadata  reset: W=%d H=%d", width, height);
    848     // Update the stream handler parameters
    849     pDecShellContext->m_pVideoStreamhandler->m_videoWidth  = width;
    850     pDecShellContext->m_pVideoStreamhandler->m_videoHeight = height;
    851     frameSize = (width * height * 3) / 2;
    852 
    853     // Configure the buffer pool
    854     if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) {
    855         ALOGV("VideoDecoder_configureFromMetadata : reset the buffer pool");
    856         VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool);
    857         pDecShellContext->m_pDecBufferPool = M4OSA_NULL;
    858     }
    859     err =  VIDEOEDITOR_BUFFER_allocatePool(&pDecShellContext->m_pDecBufferPool,
    860         MAX_DEC_BUFFERS, (M4OSA_Char*)"VIDEOEDITOR_DecodedBufferPool");
    861     VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
    862     err = VIDEOEDITOR_BUFFER_initPoolBuffers(pDecShellContext->m_pDecBufferPool,
    863                 frameSize + pDecShellContext->mGivenWidth * 2);
    864 
    865     VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
    866 
    867 cleanUp:
    868     if( M4NO_ERROR == err ) {
    869         ALOGV("VideoEditorVideoDecoder_configureFromMetadata no error");
    870     } else {
    871         if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) {
    872             VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool);
    873             pDecShellContext->m_pDecBufferPool = M4OSA_NULL;
    874         }
    875         ALOGV("VideoEditorVideoDecoder_configureFromMetadata ERROR 0x%X", err);
    876     }
    877     ALOGV("VideoEditorVideoDecoder_configureFromMetadata end");
    878     return err;
    879 }
    880 
    881 M4OSA_ERR VideoEditorVideoDecoder_destroy(M4OSA_Context pContext) {
    882     M4OSA_ERR err = M4NO_ERROR;
    883     VideoEditorVideoDecoder_Context* pDecShellContext =
    884         (VideoEditorVideoDecoder_Context*)pContext;
    885 
    886     // Input parameters check
    887     ALOGV("VideoEditorVideoDecoder_destroy begin");
    888     VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER);
    889 
    890     // Release the color converter
    891     delete pDecShellContext->mI420ColorConverter;
    892 
    893     // Destroy the graph
    894     if( pDecShellContext->mVideoDecoder != NULL ) {
    895         ALOGV("### VideoEditorVideoDecoder_destroy : releasing decoder");
    896         pDecShellContext->mVideoDecoder->stop();
    897         pDecShellContext->mVideoDecoder.clear();
    898     }
    899     pDecShellContext->mClient.disconnect();
    900     pDecShellContext->mReaderSource.clear();
    901 
    902     // Release memory
    903     if( pDecShellContext->m_pDecBufferPool != M4OSA_NULL ) {
    904         VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool);
    905         pDecShellContext->m_pDecBufferPool = M4OSA_NULL;
    906     }
    907     SAFE_FREE(pDecShellContext);
    908     pContext = NULL;
    909 
    910 cleanUp:
    911     if( M4NO_ERROR == err ) {
    912         ALOGV("VideoEditorVideoDecoder_destroy no error");
    913     } else {
    914         ALOGV("VideoEditorVideoDecoder_destroy ERROR 0x%X", err);
    915     }
    916     ALOGV("VideoEditorVideoDecoder_destroy end");
    917     return err;
    918 }
    919 
    920 M4OSA_ERR VideoEditorVideoDecoder_create(M4OSA_Context *pContext,
    921         M4_StreamHandler *pStreamHandler,
    922         M4READER_GlobalInterface *pReaderGlobalInterface,
    923         M4READER_DataInterface *pReaderDataInterface,
    924         M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) {
    925     M4OSA_ERR err = M4NO_ERROR;
    926     VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL;
    927     status_t status = OK;
    928     bool success = TRUE;
    929     int32_t colorFormat = 0;
    930     M4OSA_UInt32 size = 0;
    931     sp<MetaData> decoderMetadata = NULL;
    932     int decoderOutput = OMX_COLOR_FormatYUV420Planar;
    933 
    934     ALOGV("VideoEditorVideoDecoder_create begin");
    935     // Input parameters check
    936     VIDEOEDITOR_CHECK(M4OSA_NULL != pContext,             M4ERR_PARAMETER);
    937     VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler,       M4ERR_PARAMETER);
    938     VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER);
    939 
    940     // Context allocation & initialization
    941     SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1,
    942         "VideoEditorVideoDecoder");
    943     pDecShellContext->m_pVideoStreamhandler =
    944         (M4_VideoStreamHandler*)pStreamHandler;
    945     pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit;
    946     pDecShellContext->m_pReaderGlobal = pReaderGlobalInterface;
    947     pDecShellContext->m_pReader = pReaderDataInterface;
    948     pDecShellContext->m_lastDecodedCTS = -1;
    949     pDecShellContext->m_lastRenderCts = -1;
    950     switch( pStreamHandler->m_streamType ) {
    951         case M4DA_StreamTypeVideoH263:
    952             pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec;
    953             break;
    954         case M4DA_StreamTypeVideoMpeg4:
    955             pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec;
    956             // Parse the VOL header
    957             err = VideoEditorVideoDecoder_internalParseVideoDSI(
    958                 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\
    959                     m_basicProperties.m_pDecoderSpecificInfo,
    960                 pDecShellContext->m_pVideoStreamhandler->\
    961                     m_basicProperties.m_decoderSpecificInfoSize,
    962                 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize);
    963             VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
    964             break;
    965         case M4DA_StreamTypeVideoMpeg4Avc:
    966             pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec;
    967             break;
    968         default:
    969             VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
    970                 M4ERR_PARAMETER);
    971             break;
    972     }
    973 
    974     pDecShellContext->mNbInputFrames     = 0;
    975     pDecShellContext->mFirstInputCts     = -1.0;
    976     pDecShellContext->mLastInputCts      = -1.0;
    977     pDecShellContext->mNbRenderedFrames  = 0;
    978     pDecShellContext->mFirstRenderedCts  = -1.0;
    979     pDecShellContext->mLastRenderedCts   = -1.0;
    980     pDecShellContext->mNbOutputFrames    = 0;
    981     pDecShellContext->mFirstOutputCts    = -1;
    982     pDecShellContext->mLastOutputCts     = -1;
    983     pDecShellContext->m_pDecBufferPool   = M4OSA_NULL;
    984 
    985     // Calculate the interval between two video frames.
    986     CHECK(pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate > 0);
    987     pDecShellContext->mFrameIntervalMs =
    988             1000.0 / pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate;
    989 
    990     /**
    991      * StageFright graph building
    992      */
    993     decoderMetadata = new MetaData;
    994     switch( pDecShellContext->mDecoderType ) {
    995         case VIDEOEDITOR_kH263VideoDec:
    996             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
    997             break;
    998         case VIDEOEDITOR_kMpeg4VideoDec:
    999             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
   1000             decoderMetadata->setData(kKeyESDS, kTypeESDS,
   1001                 pStreamHandler->m_pESDSInfo,
   1002                 pStreamHandler->m_ESDSInfoSize);
   1003             break;
   1004         case VIDEOEDITOR_kH264VideoDec:
   1005             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
   1006             decoderMetadata->setData(kKeyAVCC, kTypeAVCC,
   1007                 pStreamHandler->m_pH264DecoderSpecificInfo,
   1008                 pStreamHandler->m_H264decoderSpecificInfoSize);
   1009             break;
   1010         default:
   1011             VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
   1012                 M4ERR_PARAMETER);
   1013             break;
   1014     }
   1015 
   1016     decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize);
   1017     decoderMetadata->setInt32(kKeyWidth,
   1018         pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
   1019     decoderMetadata->setInt32(kKeyHeight,
   1020         pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
   1021 
   1022     // Create the decoder source
   1023     pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource(
   1024         decoderMetadata, pDecShellContext->mDecoderType,
   1025         (void *)pDecShellContext);
   1026     VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(),
   1027         M4ERR_SF_DECODER_RSRC_FAIL);
   1028 
   1029     // Connect to the OMX client
   1030     status = pDecShellContext->mClient.connect();
   1031     VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
   1032 
   1033     // Create the decoder
   1034     pDecShellContext->mVideoDecoder = OMXCodec::Create(
   1035         pDecShellContext->mClient.interface(),
   1036         decoderMetadata, false, pDecShellContext->mReaderSource);
   1037     VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(),
   1038         M4ERR_SF_DECODER_RSRC_FAIL);
   1039 
   1040 
   1041     // Get the output color format
   1042     success = pDecShellContext->mVideoDecoder->getFormat()->findInt32(
   1043         kKeyColorFormat, &colorFormat);
   1044     VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
   1045     pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
   1046 
   1047     pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth,
   1048         pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
   1049     pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight,
   1050         pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
   1051 
   1052     // Get the color converter
   1053     pDecShellContext->mI420ColorConverter = new I420ColorConverter;
   1054     if (pDecShellContext->mI420ColorConverter->isLoaded()) {
   1055         decoderOutput = pDecShellContext->mI420ColorConverter->getDecoderOutputFormat();
   1056     }
   1057 
   1058     if (decoderOutput == OMX_COLOR_FormatYUV420Planar) {
   1059         delete pDecShellContext->mI420ColorConverter;
   1060         pDecShellContext->mI420ColorConverter = NULL;
   1061     }
   1062 
   1063     ALOGI("decoder output format = 0x%X\n", decoderOutput);
   1064 
   1065     // Configure the buffer pool from the metadata
   1066     err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext,
   1067         pDecShellContext->mVideoDecoder->getFormat().get());
   1068     VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
   1069 
   1070     // Start the graph
   1071     status = pDecShellContext->mVideoDecoder->start();
   1072     VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
   1073 
   1074     *pContext = (M4OSA_Context)pDecShellContext;
   1075 
   1076 cleanUp:
   1077     if( M4NO_ERROR == err ) {
   1078         ALOGV("VideoEditorVideoDecoder_create no error");
   1079     } else {
   1080         VideoEditorVideoDecoder_destroy(pDecShellContext);
   1081         *pContext = M4OSA_NULL;
   1082         ALOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err);
   1083     }
   1084     ALOGV("VideoEditorVideoDecoder_create : DONE");
   1085     return err;
   1086 }
   1087 
   1088 M4OSA_ERR VideoEditorVideoSoftwareDecoder_create(M4OSA_Context *pContext,
   1089         M4_StreamHandler *pStreamHandler,
   1090         M4READER_GlobalInterface *pReaderGlobalInterface,
   1091         M4READER_DataInterface *pReaderDataInterface,
   1092         M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) {
   1093     M4OSA_ERR err = M4NO_ERROR;
   1094     VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL;
   1095     status_t status = OK;
   1096     bool success = TRUE;
   1097     int32_t colorFormat = 0;
   1098     M4OSA_UInt32 size = 0;
   1099     sp<MetaData> decoderMetadata = NULL;
   1100 
   1101     ALOGV("VideoEditorVideoDecoder_create begin");
   1102     // Input parameters check
   1103     VIDEOEDITOR_CHECK(M4OSA_NULL != pContext,             M4ERR_PARAMETER);
   1104     VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler,       M4ERR_PARAMETER);
   1105     VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER);
   1106 
   1107     // Context allocation & initialization
   1108     SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1,
   1109         "VideoEditorVideoDecoder");
   1110     pDecShellContext->m_pVideoStreamhandler =
   1111         (M4_VideoStreamHandler*)pStreamHandler;
   1112     pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit;
   1113     pDecShellContext->m_pReaderGlobal = pReaderGlobalInterface;
   1114     pDecShellContext->m_pReader = pReaderDataInterface;
   1115     pDecShellContext->m_lastDecodedCTS = -1;
   1116     pDecShellContext->m_lastRenderCts = -1;
   1117     switch( pStreamHandler->m_streamType ) {
   1118         case M4DA_StreamTypeVideoH263:
   1119             pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec;
   1120             break;
   1121         case M4DA_StreamTypeVideoMpeg4:
   1122             pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec;
   1123             // Parse the VOL header
   1124             err = VideoEditorVideoDecoder_internalParseVideoDSI(
   1125                 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\
   1126                     m_basicProperties.m_pDecoderSpecificInfo,
   1127                 pDecShellContext->m_pVideoStreamhandler->\
   1128                     m_basicProperties.m_decoderSpecificInfoSize,
   1129                 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize);
   1130             VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
   1131             break;
   1132         case M4DA_StreamTypeVideoMpeg4Avc:
   1133             pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec;
   1134             break;
   1135         default:
   1136             VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
   1137                 M4ERR_PARAMETER);
   1138             break;
   1139     }
   1140 
   1141     pDecShellContext->mNbInputFrames     = 0;
   1142     pDecShellContext->mFirstInputCts     = -1.0;
   1143     pDecShellContext->mLastInputCts      = -1.0;
   1144     pDecShellContext->mNbRenderedFrames  = 0;
   1145     pDecShellContext->mFirstRenderedCts  = -1.0;
   1146     pDecShellContext->mLastRenderedCts   = -1.0;
   1147     pDecShellContext->mNbOutputFrames    = 0;
   1148     pDecShellContext->mFirstOutputCts    = -1;
   1149     pDecShellContext->mLastOutputCts     = -1;
   1150     pDecShellContext->m_pDecBufferPool   = M4OSA_NULL;
   1151 
   1152     /**
   1153      * StageFright graph building
   1154      */
   1155     decoderMetadata = new MetaData;
   1156     switch( pDecShellContext->mDecoderType ) {
   1157         case VIDEOEDITOR_kH263VideoDec:
   1158             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
   1159             break;
   1160         case VIDEOEDITOR_kMpeg4VideoDec:
   1161             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
   1162             decoderMetadata->setData(kKeyESDS, kTypeESDS,
   1163                 pStreamHandler->m_pESDSInfo,
   1164                 pStreamHandler->m_ESDSInfoSize);
   1165             break;
   1166         case VIDEOEDITOR_kH264VideoDec:
   1167             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
   1168             decoderMetadata->setData(kKeyAVCC, kTypeAVCC,
   1169                 pStreamHandler->m_pH264DecoderSpecificInfo,
   1170                 pStreamHandler->m_H264decoderSpecificInfoSize);
   1171             break;
   1172         default:
   1173             VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
   1174                 M4ERR_PARAMETER);
   1175             break;
   1176     }
   1177 
   1178     decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize);
   1179     decoderMetadata->setInt32(kKeyWidth,
   1180         pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
   1181     decoderMetadata->setInt32(kKeyHeight,
   1182         pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
   1183 
   1184     // Create the decoder source
   1185     pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource(
   1186         decoderMetadata, pDecShellContext->mDecoderType,
   1187         (void *)pDecShellContext);
   1188     VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(),
   1189         M4ERR_SF_DECODER_RSRC_FAIL);
   1190 
   1191     // Connect to the OMX client
   1192     status = pDecShellContext->mClient.connect();
   1193     VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
   1194 
   1195      ALOGI("Using software codecs only");
   1196     // Create the decoder
   1197     pDecShellContext->mVideoDecoder = OMXCodec::Create(
   1198         pDecShellContext->mClient.interface(),
   1199         decoderMetadata, false, pDecShellContext->mReaderSource,NULL,OMXCodec::kSoftwareCodecsOnly);
   1200     VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(),
   1201         M4ERR_SF_DECODER_RSRC_FAIL);
   1202 
   1203     // Get the output color format
   1204     success = pDecShellContext->mVideoDecoder->getFormat()->findInt32(
   1205         kKeyColorFormat, &colorFormat);
   1206     VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
   1207     pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
   1208 
   1209     pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth,
   1210         pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
   1211     pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight,
   1212         pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
   1213 
   1214     // Configure the buffer pool from the metadata
   1215     err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext,
   1216         pDecShellContext->mVideoDecoder->getFormat().get());
   1217     VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
   1218 
   1219     // Start the graph
   1220     status = pDecShellContext->mVideoDecoder->start();
   1221     VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
   1222 
   1223     *pContext = (M4OSA_Context)pDecShellContext;
   1224 
   1225 cleanUp:
   1226     if( M4NO_ERROR == err ) {
   1227         ALOGV("VideoEditorVideoDecoder_create no error");
   1228     } else {
   1229         VideoEditorVideoDecoder_destroy(pDecShellContext);
   1230         *pContext = M4OSA_NULL;
   1231         ALOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err);
   1232     }
   1233     ALOGV("VideoEditorVideoDecoder_create : DONE");
   1234     return err;
   1235 }
   1236 
   1237 
   1238 M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context,
   1239         M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
   1240     M4OSA_ERR lerr = M4NO_ERROR;
   1241     VideoEditorVideoDecoder_Context* pDecShellContext =
   1242         (VideoEditorVideoDecoder_Context*) context;
   1243     M4_VersionInfo* pVersionInfo;
   1244     M4DECODER_VideoSize* pVideoSize;
   1245     M4OSA_UInt32* pNextFrameCts;
   1246     M4OSA_UInt32 *plastDecodedFrameCts;
   1247     M4DECODER_AVCProfileLevel* profile;
   1248     M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo;
   1249 
   1250     ALOGV("VideoEditorVideoDecoder_getOption begin");
   1251 
   1252     switch (optionId) {
   1253         case M4DECODER_kOptionID_AVCLastDecodedFrameCTS:
   1254              plastDecodedFrameCts = (M4OSA_UInt32 *) pValue;
   1255              *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS;
   1256              break;
   1257 
   1258         case M4DECODER_kOptionID_Version:
   1259             pVersionInfo = (M4_VersionInfo*)pValue;
   1260 
   1261             pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR;
   1262             pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR;
   1263             pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION;
   1264             pVersionInfo->m_structSize=sizeof(M4_VersionInfo);
   1265             break;
   1266 
   1267         case M4DECODER_kOptionID_VideoSize:
   1268             /** Only VPS uses this Option ID. */
   1269             pVideoSize = (M4DECODER_VideoSize*)pValue;
   1270             pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth,
   1271                 (int32_t*)(&pVideoSize->m_uiWidth));
   1272             pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight,
   1273                 (int32_t*)(&pVideoSize->m_uiHeight));
   1274             ALOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d",
   1275                 pVideoSize->m_uiWidth, pVideoSize->m_uiHeight);
   1276             break;
   1277 
   1278         case M4DECODER_kOptionID_NextRenderedFrameCTS:
   1279             /** How to get this information. SF decoder does not provide this. *
   1280             ** Let us provide last decoded frame CTS as of now. *
   1281             ** Only VPS uses this Option ID. */
   1282             pNextFrameCts = (M4OSA_UInt32 *)pValue;
   1283             *pNextFrameCts = pDecShellContext->m_lastDecodedCTS;
   1284             break;
   1285         case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo:
   1286             if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) {
   1287                 (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) =
   1288                     pDecShellContext->m_Dci;
   1289             }
   1290             break;
   1291         default:
   1292             lerr = M4ERR_BAD_OPTION_ID;
   1293             break;
   1294 
   1295     }
   1296 
   1297     ALOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr);
   1298     return lerr;
   1299 }
   1300 
   1301 M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context,
   1302         M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
   1303     M4OSA_ERR lerr = M4NO_ERROR;
   1304     VideoEditorVideoDecoder_Context *pDecShellContext =
   1305         (VideoEditorVideoDecoder_Context*) context;
   1306 
   1307     ALOGV("VideoEditorVideoDecoder_setOption begin");
   1308 
   1309     switch (optionId) {
   1310         case M4DECODER_kOptionID_OutputFilter: {
   1311                 M4DECODER_OutputFilter* pOutputFilter =
   1312                     (M4DECODER_OutputFilter*) pValue;
   1313                 pDecShellContext->m_pFilter =
   1314                     (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\
   1315                     m_pFilterFunction;
   1316                 pDecShellContext->m_pFilterUserData =
   1317                     pOutputFilter->m_pFilterUserData;
   1318             }
   1319             break;
   1320         case M4DECODER_kOptionID_DeblockingFilter:
   1321             break;
   1322         default:
   1323             lerr = M4ERR_BAD_CONTEXT;
   1324             break;
   1325     }
   1326 
   1327     ALOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr);
   1328     return lerr;
   1329 }
   1330 
   1331 M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context,
   1332         M4_MediaTime* pTime, M4OSA_Bool bJump, M4OSA_UInt32 tolerance) {
   1333     M4OSA_ERR lerr = M4NO_ERROR;
   1334     VideoEditorVideoDecoder_Context* pDecShellContext =
   1335         (VideoEditorVideoDecoder_Context*) context;
   1336     int64_t lFrameTime;
   1337     MediaBuffer* pDecoderBuffer = NULL;
   1338     MediaBuffer* pNextBuffer = NULL;
   1339     status_t errStatus;
   1340     bool needSeek = bJump;
   1341 
   1342     ALOGV("VideoEditorVideoDecoder_decode begin");
   1343 
   1344     if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) {
   1345         // Do not call read(), it could lead to a freeze
   1346         ALOGV("VideoEditorVideoDecoder_decode : EOS already reached");
   1347         lerr = M4WAR_NO_MORE_AU;
   1348         goto VIDEOEDITOR_VideoDecode_cleanUP;
   1349     }
   1350     if(pDecShellContext->m_lastDecodedCTS >= *pTime) {
   1351         ALOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.",
   1352             pDecShellContext->m_lastDecodedCTS);
   1353         goto VIDEOEDITOR_VideoDecode_cleanUP;
   1354     }
   1355     if(M4OSA_TRUE == bJump) {
   1356         ALOGV("VideoEditorVideoDecoder_decode: Jump called");
   1357         pDecShellContext->m_lastDecodedCTS = -1;
   1358         pDecShellContext->m_lastRenderCts = -1;
   1359     }
   1360 
   1361     pDecShellContext->mNbInputFrames++;
   1362     if (0 > pDecShellContext->mFirstInputCts){
   1363         pDecShellContext->mFirstInputCts = *pTime;
   1364     }
   1365     pDecShellContext->mLastInputCts = *pTime;
   1366 
   1367     while (pDecoderBuffer == NULL || pDecShellContext->m_lastDecodedCTS + tolerance < *pTime) {
   1368         ALOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf",
   1369             pDecShellContext->m_lastDecodedCTS, *pTime);
   1370 
   1371         // Read the buffer from the stagefright decoder
   1372         if (needSeek) {
   1373             MediaSource::ReadOptions options;
   1374             int64_t time_us = *pTime * 1000;
   1375             options.setSeekTo(time_us, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
   1376             errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer, &options);
   1377             needSeek = false;
   1378         } else {
   1379             errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer);
   1380         }
   1381 
   1382         // Handle EOS and format change
   1383         if (errStatus == ERROR_END_OF_STREAM) {
   1384             ALOGV("End of stream reached, returning M4WAR_NO_MORE_AU ");
   1385             pDecShellContext->mReachedEOS = M4OSA_TRUE;
   1386             lerr = M4WAR_NO_MORE_AU;
   1387             // If we decoded a buffer before EOS, we still need to put it
   1388             // into the queue.
   1389             if (pDecoderBuffer && bJump) {
   1390                 copyBufferToQueue(pDecShellContext, pDecoderBuffer);
   1391             }
   1392             goto VIDEOEDITOR_VideoDecode_cleanUP;
   1393         } else if (INFO_FORMAT_CHANGED == errStatus) {
   1394             ALOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED");
   1395             lerr = VideoEditorVideoDecoder_configureFromMetadata(
   1396                 pDecShellContext,
   1397                 pDecShellContext->mVideoDecoder->getFormat().get());
   1398             if( M4NO_ERROR != lerr ) {
   1399                 ALOGV("!!! VideoEditorVideoDecoder_decode ERROR : "
   1400                     "VideoDecoder_configureFromMetadata returns 0x%X", lerr);
   1401                 break;
   1402             }
   1403             continue;
   1404         } else if (errStatus != OK) {
   1405             ALOGE("VideoEditorVideoDecoder_decode ERROR:0x%x(%d)",
   1406                 errStatus,errStatus);
   1407             lerr = errStatus;
   1408             goto VIDEOEDITOR_VideoDecode_cleanUP;
   1409         }
   1410 
   1411         // The OMXCodec client should expect to receive 0-length buffers
   1412         // and drop the 0-length buffers.
   1413         if (pNextBuffer->range_length() == 0) {
   1414             pNextBuffer->release();
   1415             continue;
   1416         }
   1417 
   1418         // Now we have a good next buffer, release the previous one.
   1419         if (pDecoderBuffer != NULL) {
   1420             pDecoderBuffer->release();
   1421             pDecoderBuffer = NULL;
   1422         }
   1423         pDecoderBuffer = pNextBuffer;
   1424 
   1425         // Record the timestamp of last decoded buffer
   1426         pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime);
   1427         pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000);
   1428         ALOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d",
   1429             (M4_MediaTime)lFrameTime, pDecoderBuffer->size() );
   1430 
   1431         /*
   1432          * We need to save a buffer if bJump == false to a queue. These
   1433          * buffers have a timestamp >= the target time, *pTime (for instance,
   1434          * the transition between two videos, or a trimming postion inside
   1435          * one video), since they are part of the transition clip or the
   1436          * trimmed video.
   1437          *
   1438          * If *pTime does not have the same value as any of the existing
   1439          * video frames, we would like to get the buffer right before *pTime
   1440          * and in the transcoding phrase, this video frame will be encoded
   1441          * as a key frame and becomes the first video frame for the transition or the
   1442          * trimmed video to be generated. This buffer must also be queued.
   1443          *
   1444          */
   1445         int64_t targetTimeMs =
   1446                 pDecShellContext->m_lastDecodedCTS +
   1447                 pDecShellContext->mFrameIntervalMs +
   1448                 tolerance;
   1449         if (!bJump || targetTimeMs > *pTime) {
   1450             lerr = copyBufferToQueue(pDecShellContext, pDecoderBuffer);
   1451             if (lerr != M4NO_ERROR) {
   1452                 goto VIDEOEDITOR_VideoDecode_cleanUP;
   1453             }
   1454         }
   1455     }
   1456 
   1457     pDecShellContext->mNbOutputFrames++;
   1458     if ( 0 > pDecShellContext->mFirstOutputCts ) {
   1459         pDecShellContext->mFirstOutputCts = *pTime;
   1460     }
   1461     pDecShellContext->mLastOutputCts = *pTime;
   1462 
   1463 VIDEOEDITOR_VideoDecode_cleanUP:
   1464     *pTime = pDecShellContext->m_lastDecodedCTS;
   1465     if (pDecoderBuffer != NULL) {
   1466         pDecoderBuffer->release();
   1467         pDecoderBuffer = NULL;
   1468     }
   1469 
   1470     ALOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr);
   1471     return lerr;
   1472 }
   1473 
   1474 static M4OSA_ERR copyBufferToQueue(
   1475     VideoEditorVideoDecoder_Context* pDecShellContext,
   1476     MediaBuffer* pDecoderBuffer) {
   1477 
   1478     M4OSA_ERR lerr = M4NO_ERROR;
   1479     VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer;
   1480 
   1481     // Get a buffer from the queue
   1482     lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool,
   1483         VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer);
   1484     if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) {
   1485         lerr = VIDEOEDITOR_BUFFER_getOldestBuffer(
   1486             pDecShellContext->m_pDecBufferPool,
   1487             VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer);
   1488         tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty;
   1489         lerr = M4NO_ERROR;
   1490     }
   1491 
   1492     if (lerr != M4NO_ERROR) return lerr;
   1493 
   1494     // Color convert or copy from the given MediaBuffer to our buffer
   1495     if (pDecShellContext->mI420ColorConverter) {
   1496         if (pDecShellContext->mI420ColorConverter->convertDecoderOutputToI420(
   1497             (uint8_t *)pDecoderBuffer->data(),// ?? + pDecoderBuffer->range_offset(),   // decoderBits
   1498             pDecShellContext->mGivenWidth,  // decoderWidth
   1499             pDecShellContext->mGivenHeight,  // decoderHeight
   1500             pDecShellContext->mCropRect,  // decoderRect
   1501             tmpDecBuffer->pData /* dstBits */) < 0) {
   1502             ALOGE("convertDecoderOutputToI420 failed");
   1503             lerr = M4ERR_NOT_IMPLEMENTED;
   1504         }
   1505     } else if (pDecShellContext->decOuputColorFormat == OMX_COLOR_FormatYUV420Planar) {
   1506         int32_t width = pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
   1507         int32_t height = pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
   1508         int32_t yPlaneSize = width * height;
   1509         int32_t uvPlaneSize = width * height / 4;
   1510         int32_t offsetSrc = 0;
   1511 
   1512         if (( width == pDecShellContext->mGivenWidth )  &&
   1513             ( height == pDecShellContext->mGivenHeight ))
   1514         {
   1515             M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset();
   1516 
   1517             memcpy((void *)tmpDecBuffer->pData, (void *)pTmpBuff, yPlaneSize);
   1518 
   1519             offsetSrc += pDecShellContext->mGivenWidth * pDecShellContext->mGivenHeight;
   1520             memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize),
   1521                 (void *)(pTmpBuff + offsetSrc), uvPlaneSize);
   1522 
   1523             offsetSrc += (pDecShellContext->mGivenWidth >> 1) * (pDecShellContext->mGivenHeight >> 1);
   1524             memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize + uvPlaneSize),
   1525                 (void *)(pTmpBuff + offsetSrc), uvPlaneSize);
   1526         }
   1527         else
   1528         {
   1529             M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset();
   1530             M4OSA_MemAddr8 pTmpBuffDst = (M4OSA_MemAddr8)tmpDecBuffer->pData;
   1531             int32_t index;
   1532 
   1533             for ( index = 0; index < height; index++)
   1534             {
   1535                 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width);
   1536                 pTmpBuffDst += width;
   1537                 pTmpBuff += pDecShellContext->mGivenWidth;
   1538             }
   1539 
   1540             pTmpBuff += (pDecShellContext->mGivenWidth * ( pDecShellContext->mGivenHeight - height));
   1541             for ( index = 0; index < height >> 1; index++)
   1542             {
   1543                 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1);
   1544                 pTmpBuffDst += width >> 1;
   1545                 pTmpBuff += pDecShellContext->mGivenWidth >> 1;
   1546             }
   1547 
   1548             pTmpBuff += ((pDecShellContext->mGivenWidth * (pDecShellContext->mGivenHeight - height)) / 4);
   1549             for ( index = 0; index < height >> 1; index++)
   1550             {
   1551                 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1);
   1552                 pTmpBuffDst += width >> 1;
   1553                 pTmpBuff += pDecShellContext->mGivenWidth >> 1;
   1554             }
   1555         }
   1556     } else {
   1557         ALOGE("VideoDecoder_decode: unexpected color format 0x%X",
   1558             pDecShellContext->decOuputColorFormat);
   1559         lerr = M4ERR_PARAMETER;
   1560     }
   1561 
   1562     tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS;
   1563     tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled;
   1564     tmpDecBuffer->size = pDecoderBuffer->size();
   1565 
   1566     return lerr;
   1567 }
   1568 
   1569 M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context,
   1570         M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane,
   1571         M4OSA_Bool bForceRender) {
   1572     M4OSA_ERR err = M4NO_ERROR;
   1573     VideoEditorVideoDecoder_Context* pDecShellContext =
   1574         (VideoEditorVideoDecoder_Context*) context;
   1575     M4OSA_UInt32 lindex, i;
   1576     M4OSA_UInt8* p_buf_src, *p_buf_dest;
   1577     M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut;
   1578     VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer
   1579                                                                   = M4OSA_NULL;
   1580     M4_MediaTime candidateTimeStamp = -1;
   1581     M4OSA_Bool bFound = M4OSA_FALSE;
   1582 
   1583     ALOGV("VideoEditorVideoDecoder_render begin");
   1584     // Input parameters check
   1585     VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER);
   1586     VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER);
   1587     VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER);
   1588 
   1589     // The output buffer is already allocated, just copy the data
   1590     if ( (*pTime <= pDecShellContext->m_lastRenderCts) &&
   1591             (M4OSA_FALSE == bForceRender) ) {
   1592         ALOGV("VIDEOEDITOR_VIDEO_render Frame in the past");
   1593         err = M4WAR_VIDEORENDERER_NO_NEW_FRAME;
   1594         goto cleanUp;
   1595     }
   1596     ALOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = "
   1597         "%lf", pDecShellContext->m_lastRenderCts, *pTime);
   1598 
   1599     /**
   1600      * Find the buffer appropriate for rendering.  */
   1601     for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) {
   1602         pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\
   1603             ->pNXPBuffer[i];
   1604         if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) {
   1605             /** Free all those buffers older than last rendered frame. */
   1606             if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\
   1607                     m_lastRenderCts) {
   1608                 pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty;
   1609             }
   1610 
   1611             /** Get the buffer with appropriate timestamp  */
   1612             if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\
   1613                     m_lastRenderCts) &&
   1614                 (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) &&
   1615                 (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) {
   1616                 bFound = M4OSA_TRUE;
   1617                 pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer;
   1618                 candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS;
   1619                 ALOGV("VideoDecoder_render: found a buffer with timestamp = %lf",
   1620                     candidateTimeStamp);
   1621             }
   1622         }
   1623     }
   1624     if (M4OSA_FALSE == bFound) {
   1625         err = M4WAR_VIDEORENDERER_NO_NEW_FRAME;
   1626         goto cleanUp;
   1627     }
   1628 
   1629     ALOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d",
   1630         pOutputPlane[0].u_width, pOutputPlane[0].u_height,
   1631         pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride);
   1632 
   1633     pDecShellContext->m_lastRenderCts = candidateTimeStamp;
   1634 
   1635     if( M4OSA_NULL != pDecShellContext->m_pFilter ) {
   1636         // Filtering was requested
   1637         M4VIFI_ImagePlane tmpPlane[3];
   1638         // Prepare the output image for conversion
   1639         tmpPlane[0].u_width   =
   1640             pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
   1641         tmpPlane[0].u_height  =
   1642             pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
   1643         tmpPlane[0].u_topleft = 0;
   1644         tmpPlane[0].u_stride  = tmpPlane[0].u_width;
   1645         tmpPlane[0].pac_data  = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData;
   1646         tmpPlane[1].u_width   = tmpPlane[0].u_width/2;
   1647         tmpPlane[1].u_height  = tmpPlane[0].u_height/2;
   1648         tmpPlane[1].u_topleft = 0;
   1649         tmpPlane[1].u_stride  = tmpPlane[0].u_stride/2;
   1650         tmpPlane[1].pac_data  = tmpPlane[0].pac_data +
   1651             (tmpPlane[0].u_stride * tmpPlane[0].u_height);
   1652         tmpPlane[2].u_width   = tmpPlane[1].u_width;
   1653         tmpPlane[2].u_height  = tmpPlane[1].u_height;
   1654         tmpPlane[2].u_topleft = 0;
   1655         tmpPlane[2].u_stride  = tmpPlane[1].u_stride;
   1656         tmpPlane[2].pac_data  = tmpPlane[1].pac_data +
   1657             (tmpPlane[1].u_stride * tmpPlane[1].u_height);
   1658 
   1659         ALOGV("VideoEditorVideoDecoder_render w = %d H = %d",
   1660             tmpPlane[0].u_width,tmpPlane[0].u_height);
   1661         pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane);
   1662     } else {
   1663         // Just copy the YUV420P buffer
   1664         M4OSA_MemAddr8 tempBuffPtr =
   1665             (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData;
   1666         M4OSA_UInt32 tempWidth =
   1667             pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
   1668         M4OSA_UInt32 tempHeight =
   1669             pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
   1670 
   1671         memcpy((void *) pOutputPlane[0].pac_data, (void *)tempBuffPtr,
   1672             tempWidth * tempHeight);
   1673         tempBuffPtr += (tempWidth * tempHeight);
   1674         memcpy((void *) pOutputPlane[1].pac_data, (void *)tempBuffPtr,
   1675             (tempWidth/2) * (tempHeight/2));
   1676         tempBuffPtr += ((tempWidth/2) * (tempHeight/2));
   1677         memcpy((void *) pOutputPlane[2].pac_data, (void *)tempBuffPtr,
   1678             (tempWidth/2) * (tempHeight/2));
   1679     }
   1680 
   1681     pDecShellContext->mNbRenderedFrames++;
   1682     if ( 0 > pDecShellContext->mFirstRenderedCts ) {
   1683         pDecShellContext->mFirstRenderedCts = *pTime;
   1684     }
   1685     pDecShellContext->mLastRenderedCts = *pTime;
   1686 
   1687 cleanUp:
   1688     if( M4NO_ERROR == err ) {
   1689         *pTime = pDecShellContext->m_lastRenderCts;
   1690         ALOGV("VideoEditorVideoDecoder_render no error");
   1691     } else {
   1692         ALOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err);
   1693     }
   1694     ALOGV("VideoEditorVideoDecoder_render end");
   1695     return err;
   1696 }
   1697 
   1698 M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType,
   1699         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1700     M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL;
   1701 
   1702     pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
   1703         sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL,
   1704         (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" );
   1705     if (M4OSA_NULL == pDecoderInterface) {
   1706         return M4ERR_ALLOC;
   1707     }
   1708 
   1709     *pDecoderType = decoderType;
   1710 
   1711     pDecoderInterface->m_pFctCreate    = VideoEditorVideoDecoder_create;
   1712     pDecoderInterface->m_pFctDestroy   = VideoEditorVideoDecoder_destroy;
   1713     pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption;
   1714     pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption;
   1715     pDecoderInterface->m_pFctDecode    = VideoEditorVideoDecoder_decode;
   1716     pDecoderInterface->m_pFctRender    = VideoEditorVideoDecoder_render;
   1717 
   1718     *pDecInterface = (M4OSA_Context)pDecoderInterface;
   1719     return M4NO_ERROR;
   1720 }
   1721 
   1722 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_VideoType decoderType,
   1723         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1724     M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL;
   1725 
   1726     pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
   1727         sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL,
   1728         (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" );
   1729     if (M4OSA_NULL == pDecoderInterface) {
   1730         return M4ERR_ALLOC;
   1731     }
   1732 
   1733     *pDecoderType = decoderType;
   1734 
   1735     pDecoderInterface->m_pFctCreate    = VideoEditorVideoSoftwareDecoder_create;
   1736     pDecoderInterface->m_pFctDestroy   = VideoEditorVideoDecoder_destroy;
   1737     pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption;
   1738     pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption;
   1739     pDecoderInterface->m_pFctDecode    = VideoEditorVideoDecoder_decode;
   1740     pDecoderInterface->m_pFctRender    = VideoEditorVideoDecoder_render;
   1741 
   1742     *pDecInterface = (M4OSA_Context)pDecoderInterface;
   1743     return M4NO_ERROR;
   1744 }
   1745 extern "C" {
   1746 
   1747 M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4(
   1748         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1749     return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4,
   1750         pDecoderType, pDecInterface);
   1751 }
   1752 
   1753 M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264(
   1754         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1755     return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC,
   1756         pDecoderType, pDecInterface);
   1757 
   1758 }
   1759 
   1760 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_MPEG4(
   1761         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1762     return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeMPEG4,
   1763         pDecoderType, pDecInterface);
   1764 }
   1765 
   1766 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_H264(
   1767         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1768     return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeAVC,
   1769         pDecoderType, pDecInterface);
   1770 
   1771 }
   1772 
   1773 M4OSA_ERR VideoEditorVideoDecoder_getVideoDecodersAndCapabilities(
   1774     M4DECODER_VideoDecoders** decoders) {
   1775     return queryVideoDecoderCapabilities(decoders);
   1776 }
   1777 
   1778 }  // extern "C"
   1779