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