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