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    M4PTO3GPP_VideoPreProcessing.c
     19  * @brief   Picture to 3gpp Service video preprocessing management.
     20  ******************************************************************************
     21  */
     22 
     23 /**
     24  *    OSAL Debug utilities */
     25 #include "M4OSA_Debug.h"
     26 
     27 /**
     28  *    OSAL Memory management */
     29 #include "M4OSA_Memory.h"
     30 
     31 /**
     32  *    Definition of the M4PTO3GPP internal context */
     33 #include "M4PTO3GPP_InternalTypes.h"
     34 
     35 /**
     36  *    Definition of the M4PTO3GPP errors */
     37 #include "M4PTO3GPP_ErrorCodes.h"
     38 
     39 /* If time increment is too low then we have an infinite alloc loop into M4ViEncCaptureFrame() */
     40 /* Time increment should match 30 fps maximum */
     41 #define M4PTO3GPP_MIN_TIME_INCREMENT 33.3333334
     42 
     43 
     44 /**
     45  ******************************************************************************
     46  * M4OSA_ERR M4PTO3GPP_applyVPP(M4VPP_Context pContext, M4VIFI_ImagePlane* pPlaneIn,
     47  *                                 M4VIFI_ImagePlane* pPlaneOut)
     48  * @brief    Call an external callback to get the picture to encode
     49  * @note    It is called by the video encoder
     50  * @param    pContext    (IN) VPP context, which actually is the M4PTO3GPP internal context
     51  *                            in our case
     52  * @param    pPlaneIn    (IN) Contains the image
     53  * @param    pPlaneOut    (IN/OUT) Pointer to an array of 3 planes that will contain the
     54  *                        output YUV420 image read with the m_pPictureCallbackFct
     55  * @return    M4NO_ERROR:    No error
     56  * @return    Any error returned by an underlaying module
     57  ******************************************************************************
     58  */
     59 /******************************************************/
     60 M4OSA_ERR M4PTO3GPP_applyVPP(M4VPP_Context pContext, M4VIFI_ImagePlane* pPlaneIn,
     61                              M4VIFI_ImagePlane* pPlaneOut)
     62 /******************************************************/
     63 {
     64     M4OSA_ERR    err;
     65     M4OSA_Double mtDuration;
     66     M4OSA_UInt32 i;
     67 
     68     /*** NOTE ***/
     69     /* It's OK to get pPlaneIn == M4OSA_NULL here                        */
     70     /* since it has been given NULL in the pFctEncode() call.            */
     71     /* It's because we use the M4PTO3GPP internal context to            */
     72     /* transmit the encoder input data.                                    */
     73     /* The input data is the image read from the m_pPictureCallbackFct    */
     74 
     75     /**
     76      *    The VPP context is actually the M4PTO3GPP context! */
     77     M4PTO3GPP_InternalContext *pC = (M4PTO3GPP_InternalContext*)(pContext);
     78 
     79     /**
     80     *  Get the picture to encode */
     81     if (M4OSA_FALSE == pC->m_bLastInternalCallBack)
     82     {
     83         err = pC->m_Params.pPictureCallbackFct(pC->m_Params.pPictureCallbackCtxt, pPlaneOut,
     84              &mtDuration);
     85 
     86         /* In case of error when getting YUV to encode (ex: error when decoding a JPEG) */
     87         if((M4NO_ERROR != err) && (((M4OSA_UInt32)M4PTO3GPP_WAR_LAST_PICTURE) != err))
     88         {
     89             return err;
     90         }
     91 
     92         /**
     93          * If end of encoding is asked by the size limitation system,
     94          * we must end the encoding the same way that when it is asked by the
     95          * picture callback (a.k.a. the integrator).
     96          * Thus we simulate the LastPicture code return: */
     97         if (M4OSA_TRUE == pC->m_IsLastPicture)
     98         {
     99             err = M4PTO3GPP_WAR_LAST_PICTURE;
    100         }
    101 
    102         if(((M4OSA_UInt32)M4PTO3GPP_WAR_LAST_PICTURE) == err)
    103         {
    104             pC->m_bLastInternalCallBack = M4OSA_TRUE; /* Toggle flag for the final call of the CB*/
    105             pC->m_IsLastPicture         = M4OSA_TRUE; /* To stop the encoder */
    106             pC->pSavedPlane             = pPlaneOut;  /* Save the last YUV plane ptr */
    107             pC->uiSavedDuration         = (M4OSA_UInt32)mtDuration; /* Save the last duration */
    108         }
    109     }
    110     else
    111     {
    112         /**< Not necessary here because the last frame duration is set to the-last-but-one by
    113                 the light writer */
    114         /**< Only necessary for pC->m_mtNextCts below...*/
    115         mtDuration = pC->uiSavedDuration;
    116 
    117 
    118         /** Copy the last YUV plane into the current one
    119          * (the last pic is splited due to the callback extra-call... */
    120         for (i=0; i<3; i++)
    121         {
    122             memcpy((void *)pPlaneOut[i].pac_data,
    123                  (void *)pC->pSavedPlane[i].pac_data,
    124                      pPlaneOut[i].u_stride * pPlaneOut[i].u_height);
    125         }
    126     }
    127 
    128     /* TimeIncrement should be 30 fps maximum */
    129     if(mtDuration < M4PTO3GPP_MIN_TIME_INCREMENT)
    130     {
    131         mtDuration = M4PTO3GPP_MIN_TIME_INCREMENT;
    132     }
    133 
    134     pC->m_mtNextCts += mtDuration;
    135 
    136     M4OSA_TRACE3_0("M4PTO3GPP_applyVPP: returning M4NO_ERROR");
    137     return M4NO_ERROR;
    138 }
    139 
    140