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 /******************************************************/
M4PTO3GPP_applyVPP(M4VPP_Context pContext,M4VIFI_ImagePlane * pPlaneIn,M4VIFI_ImagePlane * pPlaneOut)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