| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| /** |
| ****************************************************************************** |
| * @file M4PTO3GPP_VideoPreProcessing.c |
| * @brief Picture to 3gpp Service video preprocessing management. |
| ****************************************************************************** |
| */ |
| |
| /** |
| * OSAL Debug utilities */ |
| #include "M4OSA_Debug.h" |
| |
| /** |
| * OSAL Memory management */ |
| #include "M4OSA_Memory.h" |
| |
| /** |
| * Definition of the M4PTO3GPP internal context */ |
| #include "M4PTO3GPP_InternalTypes.h" |
| |
| /** |
| * Definition of the M4PTO3GPP errors */ |
| #include "M4PTO3GPP_ErrorCodes.h" |
| |
| /* If time increment is too low then we have an infinite alloc loop into M4ViEncCaptureFrame() */ |
| /* Time increment should match 30 fps maximum */ |
| #define M4PTO3GPP_MIN_TIME_INCREMENT 33.3333334 |
| |
| |
| /** |
| ****************************************************************************** |
| * M4OSA_ERR M4PTO3GPP_applyVPP(M4VPP_Context pContext, M4VIFI_ImagePlane* pPlaneIn, |
| * M4VIFI_ImagePlane* pPlaneOut) |
| * @brief Call an external callback to get the picture to encode |
| * @note It is called by the video encoder |
| * @param pContext (IN) VPP context, which actually is the M4PTO3GPP internal context |
| * in our case |
| * @param pPlaneIn (IN) Contains the image |
| * @param pPlaneOut (IN/OUT) Pointer to an array of 3 planes that will contain the |
| * output YUV420 image read with the m_pPictureCallbackFct |
| * @return M4NO_ERROR: No error |
| * @return Any error returned by an underlaying module |
| ****************************************************************************** |
| */ |
| /******************************************************/ |
| M4OSA_ERR M4PTO3GPP_applyVPP(M4VPP_Context pContext, M4VIFI_ImagePlane* pPlaneIn, |
| M4VIFI_ImagePlane* pPlaneOut) |
| /******************************************************/ |
| { |
| M4OSA_ERR err; |
| M4OSA_Double mtDuration; |
| M4OSA_UInt32 i; |
| |
| /*** NOTE ***/ |
| /* It's OK to get pPlaneIn == M4OSA_NULL here */ |
| /* since it has been given NULL in the pFctEncode() call. */ |
| /* It's because we use the M4PTO3GPP internal context to */ |
| /* transmit the encoder input data. */ |
| /* The input data is the image read from the m_pPictureCallbackFct */ |
| |
| /** |
| * The VPP context is actually the M4PTO3GPP context! */ |
| M4PTO3GPP_InternalContext *pC = (M4PTO3GPP_InternalContext*)(pContext); |
| |
| /** |
| * Get the picture to encode */ |
| if (M4OSA_FALSE == pC->m_bLastInternalCallBack) |
| { |
| err = pC->m_Params.pPictureCallbackFct(pC->m_Params.pPictureCallbackCtxt, pPlaneOut, |
| &mtDuration); |
| |
| /* In case of error when getting YUV to encode (ex: error when decoding a JPEG) */ |
| if((M4NO_ERROR != err) && (((M4OSA_UInt32)M4PTO3GPP_WAR_LAST_PICTURE) != err)) |
| { |
| return err; |
| } |
| |
| /** |
| * If end of encoding is asked by the size limitation system, |
| * we must end the encoding the same way that when it is asked by the |
| * picture callback (a.k.a. the integrator). |
| * Thus we simulate the LastPicture code return: */ |
| if (M4OSA_TRUE == pC->m_IsLastPicture) |
| { |
| err = M4PTO3GPP_WAR_LAST_PICTURE; |
| } |
| |
| if(((M4OSA_UInt32)M4PTO3GPP_WAR_LAST_PICTURE) == err) |
| { |
| pC->m_bLastInternalCallBack = M4OSA_TRUE; /* Toggle flag for the final call of the CB*/ |
| pC->m_IsLastPicture = M4OSA_TRUE; /* To stop the encoder */ |
| pC->pSavedPlane = pPlaneOut; /* Save the last YUV plane ptr */ |
| pC->uiSavedDuration = (M4OSA_UInt32)mtDuration; /* Save the last duration */ |
| } |
| } |
| else |
| { |
| /**< Not necessary here because the last frame duration is set to the-last-but-one by |
| the light writer */ |
| /**< Only necessary for pC->m_mtNextCts below...*/ |
| mtDuration = pC->uiSavedDuration; |
| |
| |
| /** Copy the last YUV plane into the current one |
| * (the last pic is splited due to the callback extra-call... */ |
| for (i=0; i<3; i++) |
| { |
| memcpy((void *)pPlaneOut[i].pac_data, |
| (void *)pC->pSavedPlane[i].pac_data, |
| pPlaneOut[i].u_stride * pPlaneOut[i].u_height); |
| } |
| } |
| |
| /* TimeIncrement should be 30 fps maximum */ |
| if(mtDuration < M4PTO3GPP_MIN_TIME_INCREMENT) |
| { |
| mtDuration = M4PTO3GPP_MIN_TIME_INCREMENT; |
| } |
| |
| pC->m_mtNextCts += mtDuration; |
| |
| M4OSA_TRACE3_0("M4PTO3GPP_applyVPP: returning M4NO_ERROR"); |
| return M4NO_ERROR; |
| } |
| |