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     // Calculate the interval between two video frames.
   1153     if(pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate > 0){
   1154         pDecShellContext->mFrameIntervalMs =
   1155             1000.0 / pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate;
   1156     }
   1157 
   1158     /**
   1159      * StageFright graph building
   1160      */
   1161     decoderMetadata = new MetaData;
   1162     switch( pDecShellContext->mDecoderType ) {
   1163         case VIDEOEDITOR_kH263VideoDec:
   1164             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
   1165             break;
   1166         case VIDEOEDITOR_kMpeg4VideoDec:
   1167             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
   1168             decoderMetadata->setData(kKeyESDS, kTypeESDS,
   1169                 pStreamHandler->m_pESDSInfo,
   1170                 pStreamHandler->m_ESDSInfoSize);
   1171             break;
   1172         case VIDEOEDITOR_kH264VideoDec:
   1173             decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
   1174             decoderMetadata->setData(kKeyAVCC, kTypeAVCC,
   1175                 pStreamHandler->m_pH264DecoderSpecificInfo,
   1176                 pStreamHandler->m_H264decoderSpecificInfoSize);
   1177             break;
   1178         default:
   1179             VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type",
   1180                 M4ERR_PARAMETER);
   1181             break;
   1182     }
   1183 
   1184     decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize);
   1185     decoderMetadata->setInt32(kKeyWidth,
   1186         pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
   1187     decoderMetadata->setInt32(kKeyHeight,
   1188         pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
   1189 
   1190     // Create the decoder source
   1191     pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource(
   1192         decoderMetadata, pDecShellContext->mDecoderType,
   1193         (void *)pDecShellContext);
   1194     VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(),
   1195         M4ERR_SF_DECODER_RSRC_FAIL);
   1196 
   1197     // Connect to the OMX client
   1198     status = pDecShellContext->mClient.connect();
   1199     VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
   1200 
   1201      ALOGI("Using software codecs only");
   1202     // Create the decoder
   1203     pDecShellContext->mVideoDecoder = OMXCodec::Create(
   1204         pDecShellContext->mClient.interface(),
   1205         decoderMetadata, false, pDecShellContext->mReaderSource,NULL,OMXCodec::kSoftwareCodecsOnly);
   1206     VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(),
   1207         M4ERR_SF_DECODER_RSRC_FAIL);
   1208 
   1209     // Get the output color format
   1210     success = pDecShellContext->mVideoDecoder->getFormat()->findInt32(
   1211         kKeyColorFormat, &colorFormat);
   1212     VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER);
   1213     pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
   1214 
   1215     pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth,
   1216         pDecShellContext->m_pVideoStreamhandler->m_videoWidth);
   1217     pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight,
   1218         pDecShellContext->m_pVideoStreamhandler->m_videoHeight);
   1219 
   1220     // Configure the buffer pool from the metadata
   1221     err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext,
   1222         pDecShellContext->mVideoDecoder->getFormat().get());
   1223     VIDEOEDITOR_CHECK(M4NO_ERROR == err, err);
   1224 
   1225     // Start the graph
   1226     status = pDecShellContext->mVideoDecoder->start();
   1227     VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL);
   1228 
   1229     *pContext = (M4OSA_Context)pDecShellContext;
   1230 
   1231 cleanUp:
   1232     if( M4NO_ERROR == err ) {
   1233         ALOGV("VideoEditorVideoDecoder_create no error");
   1234     } else {
   1235         VideoEditorVideoDecoder_destroy(pDecShellContext);
   1236         *pContext = M4OSA_NULL;
   1237         ALOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err);
   1238     }
   1239     ALOGV("VideoEditorVideoDecoder_create : DONE");
   1240     return err;
   1241 }
   1242 
   1243 
   1244 M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context,
   1245         M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
   1246     M4OSA_ERR lerr = M4NO_ERROR;
   1247     VideoEditorVideoDecoder_Context* pDecShellContext =
   1248         (VideoEditorVideoDecoder_Context*) context;
   1249     M4_VersionInfo* pVersionInfo;
   1250     M4DECODER_VideoSize* pVideoSize;
   1251     M4OSA_UInt32* pNextFrameCts;
   1252     M4OSA_UInt32 *plastDecodedFrameCts;
   1253     M4DECODER_AVCProfileLevel* profile;
   1254     M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo;
   1255 
   1256     ALOGV("VideoEditorVideoDecoder_getOption begin");
   1257 
   1258     switch (optionId) {
   1259         case M4DECODER_kOptionID_AVCLastDecodedFrameCTS:
   1260              plastDecodedFrameCts = (M4OSA_UInt32 *) pValue;
   1261              *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS;
   1262              break;
   1263 
   1264         case M4DECODER_kOptionID_Version:
   1265             pVersionInfo = (M4_VersionInfo*)pValue;
   1266 
   1267             pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR;
   1268             pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR;
   1269             pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION;
   1270             pVersionInfo->m_structSize=sizeof(M4_VersionInfo);
   1271             break;
   1272 
   1273         case M4DECODER_kOptionID_VideoSize:
   1274             /** Only VPS uses this Option ID. */
   1275             pVideoSize = (M4DECODER_VideoSize*)pValue;
   1276             pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth,
   1277                 (int32_t*)(&pVideoSize->m_uiWidth));
   1278             pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight,
   1279                 (int32_t*)(&pVideoSize->m_uiHeight));
   1280             ALOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d",
   1281                 pVideoSize->m_uiWidth, pVideoSize->m_uiHeight);
   1282             break;
   1283 
   1284         case M4DECODER_kOptionID_NextRenderedFrameCTS:
   1285             /** How to get this information. SF decoder does not provide this. *
   1286             ** Let us provide last decoded frame CTS as of now. *
   1287             ** Only VPS uses this Option ID. */
   1288             pNextFrameCts = (M4OSA_UInt32 *)pValue;
   1289             *pNextFrameCts = pDecShellContext->m_lastDecodedCTS;
   1290             break;
   1291         case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo:
   1292             if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) {
   1293                 (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) =
   1294                     pDecShellContext->m_Dci;
   1295             }
   1296             break;
   1297         default:
   1298             lerr = M4ERR_BAD_OPTION_ID;
   1299             break;
   1300 
   1301     }
   1302 
   1303     ALOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr);
   1304     return lerr;
   1305 }
   1306 
   1307 M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context,
   1308         M4OSA_OptionID optionId, M4OSA_DataOption pValue) {
   1309     M4OSA_ERR lerr = M4NO_ERROR;
   1310     VideoEditorVideoDecoder_Context *pDecShellContext =
   1311         (VideoEditorVideoDecoder_Context*) context;
   1312 
   1313     ALOGV("VideoEditorVideoDecoder_setOption begin");
   1314 
   1315     switch (optionId) {
   1316         case M4DECODER_kOptionID_OutputFilter: {
   1317                 M4DECODER_OutputFilter* pOutputFilter =
   1318                     (M4DECODER_OutputFilter*) pValue;
   1319                 pDecShellContext->m_pFilter =
   1320                     (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\
   1321                     m_pFilterFunction;
   1322                 pDecShellContext->m_pFilterUserData =
   1323                     pOutputFilter->m_pFilterUserData;
   1324             }
   1325             break;
   1326         case M4DECODER_kOptionID_DeblockingFilter:
   1327             break;
   1328         default:
   1329             lerr = M4ERR_BAD_CONTEXT;
   1330             break;
   1331     }
   1332 
   1333     ALOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr);
   1334     return lerr;
   1335 }
   1336 
   1337 M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context,
   1338         M4_MediaTime* pTime, M4OSA_Bool bJump, M4OSA_UInt32 tolerance) {
   1339     M4OSA_ERR lerr = M4NO_ERROR;
   1340     VideoEditorVideoDecoder_Context* pDecShellContext =
   1341         (VideoEditorVideoDecoder_Context*) context;
   1342     int64_t lFrameTime;
   1343     MediaBuffer* pDecoderBuffer = NULL;
   1344     MediaBuffer* pNextBuffer = NULL;
   1345     status_t errStatus;
   1346     bool needSeek = bJump;
   1347 
   1348     ALOGV("VideoEditorVideoDecoder_decode begin");
   1349 
   1350     if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) {
   1351         // Do not call read(), it could lead to a freeze
   1352         ALOGV("VideoEditorVideoDecoder_decode : EOS already reached");
   1353         lerr = M4WAR_NO_MORE_AU;
   1354         goto VIDEOEDITOR_VideoDecode_cleanUP;
   1355     }
   1356     if(pDecShellContext->m_lastDecodedCTS >= *pTime) {
   1357         ALOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.",
   1358             pDecShellContext->m_lastDecodedCTS);
   1359         goto VIDEOEDITOR_VideoDecode_cleanUP;
   1360     }
   1361     if(M4OSA_TRUE == bJump) {
   1362         ALOGV("VideoEditorVideoDecoder_decode: Jump called");
   1363         pDecShellContext->m_lastDecodedCTS = -1;
   1364         pDecShellContext->m_lastRenderCts = -1;
   1365     }
   1366 
   1367     pDecShellContext->mNbInputFrames++;
   1368     if (0 > pDecShellContext->mFirstInputCts){
   1369         pDecShellContext->mFirstInputCts = *pTime;
   1370     }
   1371     pDecShellContext->mLastInputCts = *pTime;
   1372 
   1373     while (pDecoderBuffer == NULL || pDecShellContext->m_lastDecodedCTS + tolerance < *pTime) {
   1374         ALOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf",
   1375             pDecShellContext->m_lastDecodedCTS, *pTime);
   1376 
   1377         // Read the buffer from the stagefright decoder
   1378         if (needSeek) {
   1379             MediaSource::ReadOptions options;
   1380             int64_t time_us = *pTime * 1000;
   1381             options.setSeekTo(time_us, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
   1382             errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer, &options);
   1383             needSeek = false;
   1384         } else {
   1385             errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer);
   1386         }
   1387 
   1388         // Handle EOS and format change
   1389         if (errStatus == ERROR_END_OF_STREAM) {
   1390             ALOGV("End of stream reached, returning M4WAR_NO_MORE_AU ");
   1391             pDecShellContext->mReachedEOS = M4OSA_TRUE;
   1392             lerr = M4WAR_NO_MORE_AU;
   1393             // If we decoded a buffer before EOS, we still need to put it
   1394             // into the queue.
   1395             if (pDecoderBuffer && bJump) {
   1396                 copyBufferToQueue(pDecShellContext, pDecoderBuffer);
   1397             }
   1398             goto VIDEOEDITOR_VideoDecode_cleanUP;
   1399         } else if (INFO_FORMAT_CHANGED == errStatus) {
   1400             ALOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED");
   1401             lerr = VideoEditorVideoDecoder_configureFromMetadata(
   1402                 pDecShellContext,
   1403                 pDecShellContext->mVideoDecoder->getFormat().get());
   1404             if( M4NO_ERROR != lerr ) {
   1405                 ALOGV("!!! VideoEditorVideoDecoder_decode ERROR : "
   1406                     "VideoDecoder_configureFromMetadata returns 0x%X", lerr);
   1407                 break;
   1408             }
   1409             continue;
   1410         } else if (errStatus != OK) {
   1411             ALOGE("VideoEditorVideoDecoder_decode ERROR:0x%x(%d)",
   1412                 errStatus,errStatus);
   1413             lerr = errStatus;
   1414             goto VIDEOEDITOR_VideoDecode_cleanUP;
   1415         }
   1416 
   1417         // The OMXCodec client should expect to receive 0-length buffers
   1418         // and drop the 0-length buffers.
   1419         if (pNextBuffer->range_length() == 0) {
   1420             pNextBuffer->release();
   1421             continue;
   1422         }
   1423 
   1424         // Now we have a good next buffer, release the previous one.
   1425         if (pDecoderBuffer != NULL) {
   1426             pDecoderBuffer->release();
   1427             pDecoderBuffer = NULL;
   1428         }
   1429         pDecoderBuffer = pNextBuffer;
   1430 
   1431         // Record the timestamp of last decoded buffer
   1432         pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime);
   1433         pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000);
   1434         ALOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d",
   1435             (M4_MediaTime)lFrameTime, pDecoderBuffer->size() );
   1436 
   1437         /*
   1438          * We need to save a buffer if bJump == false to a queue. These
   1439          * buffers have a timestamp >= the target time, *pTime (for instance,
   1440          * the transition between two videos, or a trimming postion inside
   1441          * one video), since they are part of the transition clip or the
   1442          * trimmed video.
   1443          *
   1444          * If *pTime does not have the same value as any of the existing
   1445          * video frames, we would like to get the buffer right before *pTime
   1446          * and in the transcoding phrase, this video frame will be encoded
   1447          * as a key frame and becomes the first video frame for the transition or the
   1448          * trimmed video to be generated. This buffer must also be queued.
   1449          *
   1450          */
   1451         int64_t targetTimeMs =
   1452                 pDecShellContext->m_lastDecodedCTS +
   1453                 pDecShellContext->mFrameIntervalMs +
   1454                 tolerance;
   1455         if (!bJump || targetTimeMs > *pTime) {
   1456             lerr = copyBufferToQueue(pDecShellContext, pDecoderBuffer);
   1457             if (lerr != M4NO_ERROR) {
   1458                 goto VIDEOEDITOR_VideoDecode_cleanUP;
   1459             }
   1460         }
   1461     }
   1462 
   1463     pDecShellContext->mNbOutputFrames++;
   1464     if ( 0 > pDecShellContext->mFirstOutputCts ) {
   1465         pDecShellContext->mFirstOutputCts = *pTime;
   1466     }
   1467     pDecShellContext->mLastOutputCts = *pTime;
   1468 
   1469 VIDEOEDITOR_VideoDecode_cleanUP:
   1470     *pTime = pDecShellContext->m_lastDecodedCTS;
   1471     if (pDecoderBuffer != NULL) {
   1472         pDecoderBuffer->release();
   1473         pDecoderBuffer = NULL;
   1474     }
   1475 
   1476     ALOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr);
   1477     return lerr;
   1478 }
   1479 
   1480 static M4OSA_ERR copyBufferToQueue(
   1481     VideoEditorVideoDecoder_Context* pDecShellContext,
   1482     MediaBuffer* pDecoderBuffer) {
   1483 
   1484     M4OSA_ERR lerr = M4NO_ERROR;
   1485     VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer;
   1486 
   1487     // Get a buffer from the queue
   1488     lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool,
   1489         VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer);
   1490     if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) {
   1491         lerr = VIDEOEDITOR_BUFFER_getOldestBuffer(
   1492             pDecShellContext->m_pDecBufferPool,
   1493             VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer);
   1494         tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty;
   1495         lerr = M4NO_ERROR;
   1496     }
   1497 
   1498     if (lerr != M4NO_ERROR) return lerr;
   1499 
   1500     // Color convert or copy from the given MediaBuffer to our buffer
   1501     if (pDecShellContext->mI420ColorConverter) {
   1502         if (pDecShellContext->mI420ColorConverter->convertDecoderOutputToI420(
   1503             (uint8_t *)pDecoderBuffer->data(),// ?? + pDecoderBuffer->range_offset(),   // decoderBits
   1504             pDecShellContext->mGivenWidth,  // decoderWidth
   1505             pDecShellContext->mGivenHeight,  // decoderHeight
   1506             pDecShellContext->mCropRect,  // decoderRect
   1507             tmpDecBuffer->pData /* dstBits */) < 0) {
   1508             ALOGE("convertDecoderOutputToI420 failed");
   1509             lerr = M4ERR_NOT_IMPLEMENTED;
   1510         }
   1511     } else if (pDecShellContext->decOuputColorFormat == OMX_COLOR_FormatYUV420Planar) {
   1512         int32_t width = pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
   1513         int32_t height = pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
   1514         int32_t yPlaneSize = width * height;
   1515         int32_t uvPlaneSize = width * height / 4;
   1516         int32_t offsetSrc = 0;
   1517 
   1518         if (( width == pDecShellContext->mGivenWidth )  &&
   1519             ( height == pDecShellContext->mGivenHeight ))
   1520         {
   1521             M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset();
   1522 
   1523             memcpy((void *)tmpDecBuffer->pData, (void *)pTmpBuff, yPlaneSize);
   1524 
   1525             offsetSrc += pDecShellContext->mGivenWidth * pDecShellContext->mGivenHeight;
   1526             memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize),
   1527                 (void *)(pTmpBuff + offsetSrc), uvPlaneSize);
   1528 
   1529             offsetSrc += (pDecShellContext->mGivenWidth >> 1) * (pDecShellContext->mGivenHeight >> 1);
   1530             memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize + uvPlaneSize),
   1531                 (void *)(pTmpBuff + offsetSrc), uvPlaneSize);
   1532         }
   1533         else
   1534         {
   1535             M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset();
   1536             M4OSA_MemAddr8 pTmpBuffDst = (M4OSA_MemAddr8)tmpDecBuffer->pData;
   1537             int32_t index;
   1538 
   1539             for ( index = 0; index < height; index++)
   1540             {
   1541                 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width);
   1542                 pTmpBuffDst += width;
   1543                 pTmpBuff += pDecShellContext->mGivenWidth;
   1544             }
   1545 
   1546             pTmpBuff += (pDecShellContext->mGivenWidth * ( pDecShellContext->mGivenHeight - height));
   1547             for ( index = 0; index < height >> 1; index++)
   1548             {
   1549                 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1);
   1550                 pTmpBuffDst += width >> 1;
   1551                 pTmpBuff += pDecShellContext->mGivenWidth >> 1;
   1552             }
   1553 
   1554             pTmpBuff += ((pDecShellContext->mGivenWidth * (pDecShellContext->mGivenHeight - height)) / 4);
   1555             for ( index = 0; index < height >> 1; index++)
   1556             {
   1557                 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1);
   1558                 pTmpBuffDst += width >> 1;
   1559                 pTmpBuff += pDecShellContext->mGivenWidth >> 1;
   1560             }
   1561         }
   1562     } else {
   1563         ALOGE("VideoDecoder_decode: unexpected color format 0x%X",
   1564             pDecShellContext->decOuputColorFormat);
   1565         lerr = M4ERR_PARAMETER;
   1566     }
   1567 
   1568     tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS;
   1569     tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled;
   1570     tmpDecBuffer->size = pDecoderBuffer->size();
   1571 
   1572     return lerr;
   1573 }
   1574 
   1575 M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context,
   1576         M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane,
   1577         M4OSA_Bool bForceRender) {
   1578     M4OSA_ERR err = M4NO_ERROR;
   1579     VideoEditorVideoDecoder_Context* pDecShellContext =
   1580         (VideoEditorVideoDecoder_Context*) context;
   1581     M4OSA_UInt32 lindex, i;
   1582     M4OSA_UInt8* p_buf_src, *p_buf_dest;
   1583     M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut;
   1584     VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer
   1585                                                                   = M4OSA_NULL;
   1586     M4_MediaTime candidateTimeStamp = -1;
   1587     M4OSA_Bool bFound = M4OSA_FALSE;
   1588 
   1589     ALOGV("VideoEditorVideoDecoder_render begin");
   1590     // Input parameters check
   1591     VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER);
   1592     VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER);
   1593     VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER);
   1594 
   1595     // The output buffer is already allocated, just copy the data
   1596     if ( (*pTime <= pDecShellContext->m_lastRenderCts) &&
   1597             (M4OSA_FALSE == bForceRender) ) {
   1598         ALOGV("VIDEOEDITOR_VIDEO_render Frame in the past");
   1599         err = M4WAR_VIDEORENDERER_NO_NEW_FRAME;
   1600         goto cleanUp;
   1601     }
   1602     ALOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = "
   1603         "%lf", pDecShellContext->m_lastRenderCts, *pTime);
   1604 
   1605     /**
   1606      * Find the buffer appropriate for rendering.  */
   1607     for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) {
   1608         pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\
   1609             ->pNXPBuffer[i];
   1610         if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) {
   1611             /** Free all those buffers older than last rendered frame. */
   1612             if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\
   1613                     m_lastRenderCts) {
   1614                 pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty;
   1615             }
   1616 
   1617             /** Get the buffer with appropriate timestamp  */
   1618             if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\
   1619                     m_lastRenderCts) &&
   1620                 (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) &&
   1621                 (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) {
   1622                 bFound = M4OSA_TRUE;
   1623                 pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer;
   1624                 candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS;
   1625                 ALOGV("VideoDecoder_render: found a buffer with timestamp = %lf",
   1626                     candidateTimeStamp);
   1627             }
   1628         }
   1629     }
   1630     if (M4OSA_FALSE == bFound) {
   1631         err = M4WAR_VIDEORENDERER_NO_NEW_FRAME;
   1632         goto cleanUp;
   1633     }
   1634 
   1635     ALOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d",
   1636         pOutputPlane[0].u_width, pOutputPlane[0].u_height,
   1637         pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride);
   1638 
   1639     pDecShellContext->m_lastRenderCts = candidateTimeStamp;
   1640 
   1641     if( M4OSA_NULL != pDecShellContext->m_pFilter ) {
   1642         // Filtering was requested
   1643         M4VIFI_ImagePlane tmpPlane[3];
   1644         // Prepare the output image for conversion
   1645         tmpPlane[0].u_width   =
   1646             pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
   1647         tmpPlane[0].u_height  =
   1648             pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
   1649         tmpPlane[0].u_topleft = 0;
   1650         tmpPlane[0].u_stride  = tmpPlane[0].u_width;
   1651         tmpPlane[0].pac_data  = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData;
   1652         tmpPlane[1].u_width   = tmpPlane[0].u_width/2;
   1653         tmpPlane[1].u_height  = tmpPlane[0].u_height/2;
   1654         tmpPlane[1].u_topleft = 0;
   1655         tmpPlane[1].u_stride  = tmpPlane[0].u_stride/2;
   1656         tmpPlane[1].pac_data  = tmpPlane[0].pac_data +
   1657             (tmpPlane[0].u_stride * tmpPlane[0].u_height);
   1658         tmpPlane[2].u_width   = tmpPlane[1].u_width;
   1659         tmpPlane[2].u_height  = tmpPlane[1].u_height;
   1660         tmpPlane[2].u_topleft = 0;
   1661         tmpPlane[2].u_stride  = tmpPlane[1].u_stride;
   1662         tmpPlane[2].pac_data  = tmpPlane[1].pac_data +
   1663             (tmpPlane[1].u_stride * tmpPlane[1].u_height);
   1664 
   1665         ALOGV("VideoEditorVideoDecoder_render w = %d H = %d",
   1666             tmpPlane[0].u_width,tmpPlane[0].u_height);
   1667         pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane);
   1668     } else {
   1669         // Just copy the YUV420P buffer
   1670         M4OSA_MemAddr8 tempBuffPtr =
   1671             (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData;
   1672         M4OSA_UInt32 tempWidth =
   1673             pDecShellContext->m_pVideoStreamhandler->m_videoWidth;
   1674         M4OSA_UInt32 tempHeight =
   1675             pDecShellContext->m_pVideoStreamhandler->m_videoHeight;
   1676 
   1677         memcpy((void *) pOutputPlane[0].pac_data, (void *)tempBuffPtr,
   1678             tempWidth * tempHeight);
   1679         tempBuffPtr += (tempWidth * tempHeight);
   1680         memcpy((void *) pOutputPlane[1].pac_data, (void *)tempBuffPtr,
   1681             (tempWidth/2) * (tempHeight/2));
   1682         tempBuffPtr += ((tempWidth/2) * (tempHeight/2));
   1683         memcpy((void *) pOutputPlane[2].pac_data, (void *)tempBuffPtr,
   1684             (tempWidth/2) * (tempHeight/2));
   1685     }
   1686 
   1687     pDecShellContext->mNbRenderedFrames++;
   1688     if ( 0 > pDecShellContext->mFirstRenderedCts ) {
   1689         pDecShellContext->mFirstRenderedCts = *pTime;
   1690     }
   1691     pDecShellContext->mLastRenderedCts = *pTime;
   1692 
   1693 cleanUp:
   1694     if( M4NO_ERROR == err ) {
   1695         *pTime = pDecShellContext->m_lastRenderCts;
   1696         ALOGV("VideoEditorVideoDecoder_render no error");
   1697     } else {
   1698         ALOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err);
   1699     }
   1700     ALOGV("VideoEditorVideoDecoder_render end");
   1701     return err;
   1702 }
   1703 
   1704 M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType,
   1705         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1706     M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL;
   1707 
   1708     pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
   1709         sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL,
   1710         (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" );
   1711     if (M4OSA_NULL == pDecoderInterface) {
   1712         return M4ERR_ALLOC;
   1713     }
   1714 
   1715     *pDecoderType = decoderType;
   1716 
   1717     pDecoderInterface->m_pFctCreate    = VideoEditorVideoDecoder_create;
   1718     pDecoderInterface->m_pFctDestroy   = VideoEditorVideoDecoder_destroy;
   1719     pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption;
   1720     pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption;
   1721     pDecoderInterface->m_pFctDecode    = VideoEditorVideoDecoder_decode;
   1722     pDecoderInterface->m_pFctRender    = VideoEditorVideoDecoder_render;
   1723 
   1724     *pDecInterface = (M4OSA_Context)pDecoderInterface;
   1725     return M4NO_ERROR;
   1726 }
   1727 
   1728 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_VideoType decoderType,
   1729         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1730     M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL;
   1731 
   1732     pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
   1733         sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL,
   1734         (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" );
   1735     if (M4OSA_NULL == pDecoderInterface) {
   1736         return M4ERR_ALLOC;
   1737     }
   1738 
   1739     *pDecoderType = decoderType;
   1740 
   1741     pDecoderInterface->m_pFctCreate    = VideoEditorVideoSoftwareDecoder_create;
   1742     pDecoderInterface->m_pFctDestroy   = VideoEditorVideoDecoder_destroy;
   1743     pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption;
   1744     pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption;
   1745     pDecoderInterface->m_pFctDecode    = VideoEditorVideoDecoder_decode;
   1746     pDecoderInterface->m_pFctRender    = VideoEditorVideoDecoder_render;
   1747 
   1748     *pDecInterface = (M4OSA_Context)pDecoderInterface;
   1749     return M4NO_ERROR;
   1750 }
   1751 extern "C" {
   1752 
   1753 M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4(
   1754         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1755     return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4,
   1756         pDecoderType, pDecInterface);
   1757 }
   1758 
   1759 M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264(
   1760         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1761     return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC,
   1762         pDecoderType, pDecInterface);
   1763 
   1764 }
   1765 
   1766 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_MPEG4(
   1767         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1768     return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeMPEG4,
   1769         pDecoderType, pDecInterface);
   1770 }
   1771 
   1772 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_H264(
   1773         M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) {
   1774     return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeAVC,
   1775         pDecoderType, pDecInterface);
   1776 
   1777 }
   1778 
   1779 M4OSA_ERR VideoEditorVideoDecoder_getVideoDecodersAndCapabilities(
   1780     M4DECODER_VideoDecoders** decoders) {
   1781     return queryVideoDecoderCapabilities(decoders);
   1782 }
   1783 
   1784 }  // extern "C"
   1785