M4PTO3GPP_VideoPreProcessing.c revision 7c9d8018755adf1857571125ba1b3598c96ea506
1/* 2 * Copyright (C) 2004-2011 NXP Software 3 * Copyright (C) 2011 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/** 18 ****************************************************************************** 19 * @file M4PTO3GPP_VideoPreProcessing.c 20 * @brief Picture to 3gpp Service video preprocessing management. 21 ****************************************************************************** 22 */ 23 24/** 25 * OSAL Debug utilities */ 26#include "M4OSA_Debug.h" 27 28/** 29 * OSAL Memory management */ 30#include "M4OSA_Memory.h" 31 32/** 33 * Definition of the M4PTO3GPP internal context */ 34#include "M4PTO3GPP_InternalTypes.h" 35 36/** 37 * Definition of the M4PTO3GPP errors */ 38#include "M4PTO3GPP_ErrorCodes.h" 39 40/* If time increment is too low then we have an infinite alloc loop into M4ViEncCaptureFrame() */ 41/* Time increment should match 30 fps maximum */ 42#define M4PTO3GPP_MIN_TIME_INCREMENT 33.3333334 43 44 45/** 46 ****************************************************************************** 47 * M4OSA_ERR M4PTO3GPP_applyVPP(M4VPP_Context pContext, M4VIFI_ImagePlane* pPlaneIn, 48 * M4VIFI_ImagePlane* pPlaneOut) 49 * @brief Call an external callback to get the picture to encode 50 * @note It is called by the video encoder 51 * @param pContext (IN) VPP context, which actually is the M4PTO3GPP internal context 52 * in our case 53 * @param pPlaneIn (IN) Contains the image 54 * @param pPlaneOut (IN/OUT) Pointer to an array of 3 planes that will contain the 55 * output YUV420 image read with the m_pPictureCallbackFct 56 * @return M4NO_ERROR: No error 57 * @return Any error returned by an underlaying module 58 ****************************************************************************** 59 */ 60/******************************************************/ 61M4OSA_ERR M4PTO3GPP_applyVPP(M4VPP_Context pContext, M4VIFI_ImagePlane* pPlaneIn, 62 M4VIFI_ImagePlane* pPlaneOut) 63/******************************************************/ 64{ 65 M4OSA_ERR err; 66 M4OSA_Double mtDuration; 67 M4OSA_UInt32 i; 68 69 /*** NOTE ***/ 70 /* It's OK to get pPlaneIn == M4OSA_NULL here */ 71 /* since it has been given NULL in the pFctEncode() call. */ 72 /* It's because we use the M4PTO3GPP internal context to */ 73 /* transmit the encoder input data. */ 74 /* The input data is the image read from the m_pPictureCallbackFct */ 75 76 /** 77 * The VPP context is actually the M4PTO3GPP context! */ 78 M4PTO3GPP_InternalContext *pC = (M4PTO3GPP_InternalContext*)(pContext); 79 80 /** 81 * Get the picture to encode */ 82 if (M4OSA_FALSE == pC->m_bLastInternalCallBack) 83 { 84 err = pC->m_Params.pPictureCallbackFct(pC->m_Params.pPictureCallbackCtxt, pPlaneOut, 85 &mtDuration); 86 87 /* In case of error when getting YUV to encode (ex: error when decoding a JPEG) */ 88 if((M4NO_ERROR != err) && (((M4OSA_UInt32)M4PTO3GPP_WAR_LAST_PICTURE) != err)) 89 { 90 return err; 91 } 92 93 /** 94 * If end of encoding is asked by the size limitation system, 95 * we must end the encoding the same way that when it is asked by the 96 * picture callback (a.k.a. the integrator). 97 * Thus we simulate the LastPicture code return: */ 98 if (M4OSA_TRUE == pC->m_IsLastPicture) 99 { 100 err = M4PTO3GPP_WAR_LAST_PICTURE; 101 } 102 103 if(((M4OSA_UInt32)M4PTO3GPP_WAR_LAST_PICTURE) == err) 104 { 105 pC->m_bLastInternalCallBack = M4OSA_TRUE; /* Toggle flag for the final call of the CB*/ 106 pC->m_IsLastPicture = M4OSA_TRUE; /* To stop the encoder */ 107 pC->pSavedPlane = pPlaneOut; /* Save the last YUV plane ptr */ 108 pC->uiSavedDuration = (M4OSA_UInt32)mtDuration; /* Save the last duration */ 109 } 110 } 111 else 112 { 113 /**< Not necessary here because the last frame duration is set to the-last-but-one by 114 the light writer */ 115 /**< Only necessary for pC->m_mtNextCts below...*/ 116 mtDuration = pC->uiSavedDuration; 117 118 119 /** Copy the last YUV plane into the current one 120 * (the last pic is splited due to the callback extra-call... */ 121 for (i=0; i<3; i++) 122 { 123 M4OSA_memcpy((M4OSA_MemAddr8)pPlaneOut[i].pac_data, 124 (M4OSA_MemAddr8)pC->pSavedPlane[i].pac_data, 125 pPlaneOut[i].u_stride * pPlaneOut[i].u_height); 126 } 127 } 128 129 /* TimeIncrement should be 30 fps maximum */ 130 if(mtDuration < M4PTO3GPP_MIN_TIME_INCREMENT) 131 { 132 mtDuration = M4PTO3GPP_MIN_TIME_INCREMENT; 133 } 134 135 pC->m_mtNextCts += mtDuration; 136 137 M4OSA_TRACE3_0("M4PTO3GPP_applyVPP: returning M4NO_ERROR"); 138 return M4NO_ERROR; 139} 140 141