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    M4DECODER_Null.c
     19  * @brief   Implementation of the Null decoder public interface
     20  * @note    This file implements a "null" video decoder, i.e. a decoder
     21  *          that does nothing
     22 *************************************************************************
     23 */
     24 #include "NXPSW_CompilerSwitches.h"
     25 
     26 #include "M4OSA_Types.h"
     27 #include "M4OSA_Debug.h"
     28 #include "M4TOOL_VersionInfo.h"
     29 #include "M4DA_Types.h"
     30 #include "M4DECODER_Common.h"
     31 #include "M4DECODER_Null.h"
     32 
     33 /**
     34  ************************************************************************
     35  * NULL Video Decoder version information
     36  ************************************************************************
     37 */
     38 /* CHANGE_VERSION_HERE */
     39 #define M4DECODER_NULL_MAJOR    1
     40 #define M4DECODER_NULL_MINOR    0
     41 #define M4DECODER_NULL_REVISION 0
     42 
     43 /**
     44  ************************************************************************
     45  * structure    M4_VideoHandler_Context
     46  * @brief       Defines the internal context of a video decoder instance
     47  * @note        The context is allocated and freed by the video decoder
     48  ************************************************************************
     49 */
     50 typedef struct {
     51     void*                    m_pLibrary;            // Core library identifier
     52     M4OSA_Int32              m_DecoderId;           // Core decoder identifier
     53     M4OSA_Int32              m_RendererId;          // Core renderer identifier
     54     M4_VideoStreamHandler*   m_pVideoStreamhandler; // Video stream description
     55     M4_AccessUnit*           m_pNextAccessUnitToDecode; // Access unit used to
     56                                                         // read and decode one frame
     57     void*                    m_pUserData;           // Pointer to any user data
     58     M4READER_DataInterface*  m_pReader;             // Reader data interface
     59     M4OSA_Bool               m_bDoRendering;        // Decides if render required
     60     M4OSA_Int32              m_structSize;          // Size of the structure
     61 
     62     M4DECODER_OutputFilter* m_pVideoFilter;         // Color conversion filter
     63     M4VIFI_ImagePlane       *pDecYuvData;           // Pointer to Yuv data plane
     64     M4VIFI_ImagePlane       *pDecYuvWithEffect;     // Pointer to Yuv plane with color effect
     65     M4OSA_Bool               bYuvWithEffectSet;     // Original Yuv data OR Yuv with color effect
     66 
     67 } M4_VideoHandler_Context;
     68 
     69 /***********************************************************************/
     70 /************** M4DECODER_VideoInterface implementation ****************/
     71 /***********************************************************************/
     72 
     73 /**
     74  ************************************************************************
     75  * @brief   Creates an instance of the decoder
     76  * @note    Allocates the context
     77  *
     78  * @param   pContext:       (OUT)   Context of the decoder
     79  * @param   pStreamHandler: (IN)    Pointer to a video stream description
     80  * @param   pSrcInterface:  (IN)    Pointer to the M4READER_DataInterface
     81  *                                  structure that must be used by the
     82  *                                  decoder to read data from the stream
     83  * @param   pAccessUnit     (IN)    Pointer to an access unit
     84  *                                  (allocated by the caller) where decoded data
     85  *                                  are stored
     86  *
     87  * @return  M4NO_ERROR              There is no error
     88  * @return  M4ERR_STATE             State automaton is not applied
     89  * @return  M4ERR_ALLOC             A memory allocation has failed
     90  * @return  M4ERR_PARAMETER         At least one input parameter is not proper
     91  ************************************************************************
     92 */
     93 M4OSA_ERR M4DECODER_NULL_create(M4OSA_Context *pContext,
     94                                 M4_StreamHandler *pStreamHandler,
     95                                 M4READER_GlobalInterface *pReaderGlobalInterface,
     96                                 M4READER_DataInterface *pReaderDataInterface,
     97                                 M4_AccessUnit* pAccessUnit,
     98                                 M4OSA_Void* pUserData) {
     99 
    100     M4_VideoHandler_Context* pStreamContext = M4OSA_NULL;
    101 
    102     *pContext = M4OSA_NULL;
    103     pStreamContext = (M4_VideoHandler_Context*)M4OSA_32bitAlignedMalloc (
    104                         sizeof(M4_VideoHandler_Context), M4DECODER_MPEG4,
    105                         (M4OSA_Char *)"M4_VideoHandler_Context");
    106     if (pStreamContext == 0) {
    107         return M4ERR_ALLOC;
    108     }
    109 
    110     pStreamContext->m_structSize = sizeof(M4_VideoHandler_Context);
    111     pStreamContext->m_pNextAccessUnitToDecode = M4OSA_NULL;
    112     pStreamContext->m_pLibrary              = M4OSA_NULL;
    113     pStreamContext->m_pVideoStreamhandler   = M4OSA_NULL;
    114     pStreamContext->m_DecoderId             = -1;
    115     pStreamContext->m_RendererId            = -1;
    116 
    117     pStreamContext->m_pUserData = M4OSA_NULL;
    118     pStreamContext->m_bDoRendering = M4OSA_TRUE;
    119     pStreamContext->m_pVideoFilter = M4OSA_NULL;
    120     pStreamContext->bYuvWithEffectSet = M4OSA_FALSE;
    121 
    122     *pContext=pStreamContext;
    123     return M4NO_ERROR;
    124 }
    125 
    126 /**
    127  ************************************************************************
    128  * @brief   Destroy the instance of the decoder
    129  * @note    After this call the context is invalid
    130  *
    131  * @param   context:    (IN)    Context of the decoder
    132  *
    133  * @return  M4NO_ERROR          There is no error
    134  * @return  M4ERR_PARAMETER     The context is invalid
    135  ************************************************************************
    136 */
    137 M4OSA_ERR M4DECODER_NULL_destroy(M4OSA_Context pContext) {
    138 
    139     M4_VideoHandler_Context* pStreamContext = (M4_VideoHandler_Context*)pContext;
    140 
    141     M4OSA_DEBUG_IF1((M4OSA_NULL == pStreamContext),
    142         M4ERR_PARAMETER, "M4DECODER_NULL_destroy: invalid context pointer");
    143 
    144     free(pStreamContext);
    145 
    146     return M4NO_ERROR;
    147 }
    148 
    149 /**
    150  ************************************************************************
    151  * @brief   Get an option value from the decoder
    152  * @note    This function allows the caller to retrieve a property value:
    153  *
    154  * @param   context:    (IN)        Context of the decoder
    155  * @param   optionId:   (IN)        Indicates the option to get
    156  * @param   pValue:     (IN/OUT)    Pointer to structure or value where
    157  *                                  option is stored
    158  *
    159  * @return  M4NO_ERROR              There is no error
    160  * @return  M4ERR_PARAMETER         The context is invalid (in DEBUG only)
    161  * @return  M4ERR_BAD_OPTION_ID     When the option ID is not a valid one
    162  * @return  M4ERR_STATE             State automaton is not applied
    163  * @return  M4ERR_NOT_IMPLEMENTED   Function not implemented
    164  ************************************************************************
    165 */
    166 M4OSA_ERR M4DECODER_NULL_getOption(M4OSA_Context context,
    167                                    M4OSA_OptionID optionId,
    168                                    M4OSA_DataOption  pValue) {
    169 
    170     return M4ERR_NOT_IMPLEMENTED;
    171 }
    172 
    173 /**
    174  ************************************************************************
    175  * @brief   Set an option value of the decoder
    176  * @note    Allows the caller to set a property value:
    177  *
    178  * @param   context:    (IN)        Context of the decoder
    179  * @param   optionId:   (IN)        Identifier indicating the option to set
    180  * @param   pValue:     (IN)        Pointer to structure or value
    181  *                                  where option is stored
    182  *
    183  * @return  M4NO_ERROR              There is no error
    184  * @return  M4ERR_BAD_OPTION_ID     The option ID is not a valid one
    185  * @return  M4ERR_STATE             State automaton is not applied
    186  * @return  M4ERR_PARAMETER         The option parameter is invalid
    187  ************************************************************************
    188 */
    189 M4OSA_ERR M4DECODER_NULL_setOption(M4OSA_Context context,
    190                                    M4OSA_OptionID optionId,
    191                                    M4OSA_DataOption pValue) {
    192 
    193     M4DECODER_OutputFilter *pFilterOption;
    194 
    195     M4_VideoHandler_Context *pStreamContext =
    196         (M4_VideoHandler_Context*)context;
    197 
    198     M4OSA_ERR err = M4NO_ERROR;
    199     M4OSA_UInt32 height = 0;
    200     M4OSA_UInt8 *p_src,*p_des;
    201     M4VIFI_ImagePlane* pTempDecYuvData = M4OSA_NULL;
    202 
    203     switch (optionId) {
    204         case M4DECODER_kOptionID_DecYuvData:
    205             pStreamContext->pDecYuvData = (M4VIFI_ImagePlane *)pValue;
    206             break;
    207 
    208         case M4DECODER_kOptionID_YuvWithEffectContiguous:
    209             pStreamContext->pDecYuvWithEffect = (M4VIFI_ImagePlane *)pValue;
    210             break;
    211 
    212         case M4DECODER_kOptionID_EnableYuvWithEffect:
    213             pStreamContext->bYuvWithEffectSet = (M4OSA_Bool)pValue;
    214             break;
    215 
    216         case M4DECODER_kOptionID_YuvWithEffectNonContiguous:
    217             pTempDecYuvData =  (M4VIFI_ImagePlane *)pValue;
    218 
    219             p_des = pStreamContext->pDecYuvWithEffect[0].pac_data +
    220                  pStreamContext->pDecYuvWithEffect[0].u_topleft;
    221             p_src = pTempDecYuvData[0].pac_data +
    222                  pTempDecYuvData[0].u_topleft;
    223 
    224             for (height = 0; height<pStreamContext->pDecYuvWithEffect[0].u_height;
    225              height++) {
    226                 memcpy((void *)p_des, (void *)p_src,
    227                  pStreamContext->pDecYuvWithEffect[0].u_width);
    228 
    229                 p_des += pStreamContext->pDecYuvWithEffect[0].u_stride;
    230                 p_src += pTempDecYuvData[0].u_stride;
    231             }
    232 
    233             p_des = pStreamContext->pDecYuvWithEffect[1].pac_data +
    234              pStreamContext->pDecYuvWithEffect[1].u_topleft;
    235             p_src = pTempDecYuvData[1].pac_data +
    236              pTempDecYuvData[1].u_topleft;
    237 
    238             for (height = 0; height<pStreamContext->pDecYuvWithEffect[1].u_height;
    239              height++) {
    240                 memcpy((void *)p_des, (void *)p_src,
    241                  pStreamContext->pDecYuvWithEffect[1].u_width);
    242 
    243                 p_des += pStreamContext->pDecYuvWithEffect[1].u_stride;
    244                 p_src += pTempDecYuvData[1].u_stride;
    245             }
    246 
    247             p_des = pStreamContext->pDecYuvWithEffect[2].pac_data +
    248              pStreamContext->pDecYuvWithEffect[2].u_topleft;
    249             p_src = pTempDecYuvData[2].pac_data +
    250              pTempDecYuvData[2].u_topleft;
    251 
    252             for (height = 0; height<pStreamContext->pDecYuvWithEffect[2].u_height;
    253              height++) {
    254                 memcpy((void *)p_des, (void *)p_src,
    255                  pStreamContext->pDecYuvWithEffect[2].u_width);
    256 
    257                 p_des += pStreamContext->pDecYuvWithEffect[2].u_stride;
    258                 p_src += pTempDecYuvData[2].u_stride;
    259             }
    260             break;
    261 
    262         case M4DECODER_kOptionID_OutputFilter:
    263             pFilterOption = (M4DECODER_OutputFilter*)pValue;
    264             break;
    265 
    266         case M4DECODER_kOptionID_DeblockingFilter:
    267             err = M4ERR_BAD_OPTION_ID;
    268             break;
    269 
    270         default:
    271             err = M4ERR_BAD_OPTION_ID;
    272             break;
    273     }
    274     return err;
    275 }
    276 
    277 /**
    278  ************************************************************************
    279  * @brief   Decode video Access Units up to a target time
    280  * @note    Parse and decode the video until it can output a decoded image
    281  *          for which the composition time is equal or greater to the
    282  *          passed targeted time.
    283  *          The data are read from the reader data interface passed to
    284  *          M4DECODER_MPEG4_create.
    285  *
    286  * @param   context:    (IN)        Context of the decoder
    287  * @param   pTime:      (IN/OUT)    IN: Time to decode up to (in msec)
    288  *                                  OUT:Time of the last decoded frame (in msec)
    289  * @param   bJump:      (IN)        0 if no jump occured just before this call
    290  *                                  1 if a a jump has just been made
    291  * @return  M4NO_ERROR              there is no error
    292  * @return  M4ERR_PARAMETER         at least one parameter is not properly set
    293  * @return  M4WAR_NO_MORE_AU        there is no more access unit to decode (EOS)
    294  ************************************************************************
    295 */
    296 M4OSA_ERR M4DECODER_NULL_decode(M4OSA_Context context,
    297                                 M4_MediaTime* pTime, M4OSA_Bool bJump,
    298                                 M4OSA_UInt32 tolerance) {
    299 
    300     // Do nothing; input time stamp itself returned
    301     return M4NO_ERROR;
    302 }
    303 
    304 /**
    305  ************************************************************************
    306  * @brief   Renders the video at the specified time.
    307  * @note
    308  * @param   context:     (IN)       Context of the decoder
    309  * @param   pTime:       (IN/OUT)   IN: Time to render to (in msecs)
    310  *                                  OUT:Time of the rendered frame (in ms)
    311  * @param   pOutputPlane:(OUT)      Output plane filled with decoded data
    312  * @param   bForceRender:(IN)       1 if the image must be rendered even it
    313  *                                  has been rendered already
    314  *                                  0 if not
    315  *
    316  * @return  M4NO_ERROR              There is no error
    317  * @return  M4ERR_PARAMETER         At least one parameter is not properly set
    318  * @return  M4ERR_STATE             State automaton is not applied
    319  * @return  M4ERR_ALLOC             There is no more available memory
    320  * @return  M4WAR_VIDEORENDERER_NO_NEW_FRAME    If the frame has already been rendered
    321  ************************************************************************
    322 */
    323 M4OSA_ERR M4DECODER_NULL_render(M4OSA_Context context, M4_MediaTime* pTime,
    324                                 M4VIFI_ImagePlane* pOutputPlane,
    325                                 M4OSA_Bool bForceRender) {
    326 
    327     M4OSA_ERR err = M4NO_ERROR;
    328     M4OSA_UInt32 height;
    329     M4OSA_UInt8 *p_src,*p_des;
    330     M4_VideoHandler_Context*    pStreamContext =
    331         (M4_VideoHandler_Context*)context;
    332 
    333     if (pStreamContext->bYuvWithEffectSet == M4OSA_TRUE) {
    334 
    335         p_des = pOutputPlane[0].pac_data + pOutputPlane[0].u_topleft;
    336         p_src = pStreamContext->pDecYuvWithEffect[0].pac_data +
    337          pStreamContext->pDecYuvWithEffect[0].u_topleft;
    338 
    339         for (height = 0; height<pOutputPlane[0].u_height; height++) {
    340             memcpy((void *)p_des, (void *)p_src, pOutputPlane[0].u_width);
    341             p_des += pOutputPlane[0].u_stride;
    342             p_src += pStreamContext->pDecYuvWithEffect[0].u_stride;
    343         }
    344 
    345         p_des = pOutputPlane[1].pac_data + pOutputPlane[1].u_topleft;
    346         p_src = pStreamContext->pDecYuvWithEffect[1].pac_data +
    347          pStreamContext->pDecYuvWithEffect[1].u_topleft;
    348 
    349         for (height = 0; height<pOutputPlane[1].u_height; height++) {
    350             memcpy((void *)p_des, (void *)p_src, pOutputPlane[1].u_width);
    351             p_des += pOutputPlane[1].u_stride;
    352             p_src += pStreamContext->pDecYuvWithEffect[1].u_stride;
    353         }
    354 
    355         p_des = pOutputPlane[2].pac_data + pOutputPlane[2].u_topleft;
    356         p_src = pStreamContext->pDecYuvWithEffect[2].pac_data +
    357          pStreamContext->pDecYuvWithEffect[2].u_topleft;
    358 
    359         for (height = 0; height<pOutputPlane[2].u_height; height++) {
    360             memcpy((void *)p_des, (void *)p_src, pOutputPlane[2].u_width);
    361             p_des += pOutputPlane[2].u_stride;
    362             p_src += pStreamContext->pDecYuvWithEffect[2].u_stride;
    363         }
    364     } else {
    365 
    366         p_des = pOutputPlane[0].pac_data + pOutputPlane[0].u_topleft;
    367         p_src = pStreamContext->pDecYuvData[0].pac_data +
    368          pStreamContext->pDecYuvData[0].u_topleft;
    369 
    370         for (height = 0; height<pOutputPlane[0].u_height; height++) {
    371             memcpy((void *)p_des, (void *)p_src, pOutputPlane[0].u_width);
    372             p_des += pOutputPlane[0].u_stride;
    373             p_src += pStreamContext->pDecYuvData[0].u_stride;
    374         }
    375 
    376         p_des = pOutputPlane[1].pac_data + pOutputPlane[1].u_topleft;
    377         p_src = pStreamContext->pDecYuvData[1].pac_data +
    378          pStreamContext->pDecYuvData[1].u_topleft;
    379 
    380         for (height = 0; height<pOutputPlane[1].u_height; height++) {
    381             memcpy((void *)p_des, (void *)p_src, pOutputPlane[1].u_width);
    382             p_des += pOutputPlane[1].u_stride;
    383             p_src += pStreamContext->pDecYuvData[1].u_stride;
    384         }
    385 
    386         p_des = pOutputPlane[2].pac_data + pOutputPlane[2].u_topleft;
    387         p_src = pStreamContext->pDecYuvData[2].pac_data +
    388          pStreamContext->pDecYuvData[2].u_topleft;
    389 
    390         for (height = 0; height<pOutputPlane[2].u_height; height++) {
    391             memcpy((void *)p_des,(void *)p_src,pOutputPlane[2].u_width);
    392             p_des += pOutputPlane[2].u_stride;
    393             p_src += pStreamContext->pDecYuvData[2].u_stride;
    394         }
    395     }
    396     return err;
    397 }
    398 
    399 /**
    400  ************************************************************************
    401  * @brief Retrieves the interface implemented by the decoder
    402  * @param pDecoderType        : Pointer to a M4DECODER_VideoType
    403  *                             (allocated by the caller)
    404  *                             that will be filled with the decoder type
    405  * @param pDecoderInterface   : Address of a pointer that will be set to
    406  *                              the interface implemented by this decoder.
    407  *                              The interface is a structure allocated by
    408  *                              this function and must be freed by the caller.
    409  *
    410  * @returns : M4NO_ERROR  if OK
    411  *            M4ERR_ALLOC if allocation failed
    412  ************************************************************************
    413 */
    414 M4OSA_ERR M4DECODER_NULL_getInterface (M4DECODER_VideoType *pDecoderType,
    415                             M4DECODER_VideoInterface **pDecoderInterface) {
    416 
    417     *pDecoderInterface =
    418         (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
    419          sizeof(M4DECODER_VideoInterface),
    420          M4DECODER_MPEG4, (M4OSA_Char *)"M4DECODER_VideoInterface");
    421 
    422     if (M4OSA_NULL == *pDecoderInterface) {
    423         return M4ERR_ALLOC;
    424     }
    425 
    426     *pDecoderType = M4DECODER_kVideoTypeYUV420P;
    427 
    428     (*pDecoderInterface)->m_pFctCreate    = M4DECODER_NULL_create;
    429     (*pDecoderInterface)->m_pFctDestroy   = M4DECODER_NULL_destroy;
    430     (*pDecoderInterface)->m_pFctGetOption = M4DECODER_NULL_getOption;
    431     (*pDecoderInterface)->m_pFctSetOption = M4DECODER_NULL_setOption;
    432     (*pDecoderInterface)->m_pFctDecode    = M4DECODER_NULL_decode;
    433     (*pDecoderInterface)->m_pFctRender    = M4DECODER_NULL_render;
    434 
    435     return M4NO_ERROR;
    436 }
    437