• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    M4DECODER_Null.c
19  * @brief   Implementation of the Null decoder public interface
20  * @note    This file implements a "null" video decoder, i.e. a decoder
21  *          that does nothing
22 *************************************************************************
23 */
24 #include "NXPSW_CompilerSwitches.h"
25 
26 #include "M4OSA_Types.h"
27 #include "M4OSA_Debug.h"
28 #include "M4TOOL_VersionInfo.h"
29 #include "M4DA_Types.h"
30 #include "M4DECODER_Common.h"
31 #include "M4DECODER_Null.h"
32 
33 /**
34  ************************************************************************
35  * NULL Video Decoder version information
36  ************************************************************************
37 */
38 /* CHANGE_VERSION_HERE */
39 #define M4DECODER_NULL_MAJOR    1
40 #define M4DECODER_NULL_MINOR    0
41 #define M4DECODER_NULL_REVISION 0
42 
43 /**
44  ************************************************************************
45  * structure    M4_VideoHandler_Context
46  * @brief       Defines the internal context of a video decoder instance
47  * @note        The context is allocated and freed by the video decoder
48  ************************************************************************
49 */
50 typedef struct {
51     void*                    m_pLibrary;            // Core library identifier
52     M4OSA_Int32              m_DecoderId;           // Core decoder identifier
53     M4OSA_Int32              m_RendererId;          // Core renderer identifier
54     M4_VideoStreamHandler*   m_pVideoStreamhandler; // Video stream description
55     M4_AccessUnit*           m_pNextAccessUnitToDecode; // Access unit used to
56                                                         // read and decode one frame
57     void*                    m_pUserData;           // Pointer to any user data
58     M4READER_DataInterface*  m_pReader;             // Reader data interface
59     M4OSA_Bool               m_bDoRendering;        // Decides if render required
60     M4OSA_Int32              m_structSize;          // Size of the structure
61 
62     M4DECODER_OutputFilter* m_pVideoFilter;         // Color conversion filter
63     M4VIFI_ImagePlane       *pDecYuvData;           // Pointer to Yuv data plane
64     M4VIFI_ImagePlane       *pDecYuvWithEffect;     // Pointer to Yuv plane with color effect
65     M4OSA_Bool               bYuvWithEffectSet;     // Original Yuv data OR Yuv with color effect
66 
67 } M4_VideoHandler_Context;
68 
69 /***********************************************************************/
70 /************** M4DECODER_VideoInterface implementation ****************/
71 /***********************************************************************/
72 
73 /**
74  ************************************************************************
75  * @brief   Creates an instance of the decoder
76  * @note    Allocates the context
77  *
78  * @param   pContext:       (OUT)   Context of the decoder
79  * @param   pStreamHandler: (IN)    Pointer to a video stream description
80  * @param   pSrcInterface:  (IN)    Pointer to the M4READER_DataInterface
81  *                                  structure that must be used by the
82  *                                  decoder to read data from the stream
83  * @param   pAccessUnit     (IN)    Pointer to an access unit
84  *                                  (allocated by the caller) where decoded data
85  *                                  are stored
86  *
87  * @return  M4NO_ERROR              There is no error
88  * @return  M4ERR_STATE             State automaton is not applied
89  * @return  M4ERR_ALLOC             A memory allocation has failed
90  * @return  M4ERR_PARAMETER         At least one input parameter is not proper
91  ************************************************************************
92 */
M4DECODER_NULL_create(M4OSA_Context * pContext,M4_StreamHandler * pStreamHandler,M4READER_GlobalInterface * pReaderGlobalInterface,M4READER_DataInterface * pReaderDataInterface,M4_AccessUnit * pAccessUnit,M4OSA_Void * pUserData)93 M4OSA_ERR M4DECODER_NULL_create(M4OSA_Context *pContext,
94                                 M4_StreamHandler *pStreamHandler,
95                                 M4READER_GlobalInterface *pReaderGlobalInterface,
96                                 M4READER_DataInterface *pReaderDataInterface,
97                                 M4_AccessUnit* pAccessUnit,
98                                 M4OSA_Void* pUserData) {
99 
100     M4_VideoHandler_Context* pStreamContext = M4OSA_NULL;
101 
102     *pContext = M4OSA_NULL;
103     pStreamContext = (M4_VideoHandler_Context*)M4OSA_32bitAlignedMalloc (
104                         sizeof(M4_VideoHandler_Context), M4DECODER_MPEG4,
105                         (M4OSA_Char *)"M4_VideoHandler_Context");
106     if (pStreamContext == 0) {
107         return M4ERR_ALLOC;
108     }
109 
110     pStreamContext->m_structSize = sizeof(M4_VideoHandler_Context);
111     pStreamContext->m_pNextAccessUnitToDecode = M4OSA_NULL;
112     pStreamContext->m_pLibrary              = M4OSA_NULL;
113     pStreamContext->m_pVideoStreamhandler   = M4OSA_NULL;
114     pStreamContext->m_DecoderId             = -1;
115     pStreamContext->m_RendererId            = -1;
116 
117     pStreamContext->m_pUserData = M4OSA_NULL;
118     pStreamContext->m_bDoRendering = M4OSA_TRUE;
119     pStreamContext->m_pVideoFilter = M4OSA_NULL;
120     pStreamContext->bYuvWithEffectSet = M4OSA_FALSE;
121 
122     *pContext=pStreamContext;
123     return M4NO_ERROR;
124 }
125 
126 /**
127  ************************************************************************
128  * @brief   Destroy the instance of the decoder
129  * @note    After this call the context is invalid
130  *
131  * @param   context:    (IN)    Context of the decoder
132  *
133  * @return  M4NO_ERROR          There is no error
134  * @return  M4ERR_PARAMETER     The context is invalid
135  ************************************************************************
136 */
M4DECODER_NULL_destroy(M4OSA_Context pContext)137 M4OSA_ERR M4DECODER_NULL_destroy(M4OSA_Context pContext) {
138 
139     M4_VideoHandler_Context* pStreamContext = (M4_VideoHandler_Context*)pContext;
140 
141     M4OSA_DEBUG_IF1((M4OSA_NULL == pStreamContext),
142         M4ERR_PARAMETER, "M4DECODER_NULL_destroy: invalid context pointer");
143 
144     free(pStreamContext);
145 
146     return M4NO_ERROR;
147 }
148 
149 /**
150  ************************************************************************
151  * @brief   Get an option value from the decoder
152  * @note    This function allows the caller to retrieve a property value:
153  *
154  * @param   context:    (IN)        Context of the decoder
155  * @param   optionId:   (IN)        Indicates the option to get
156  * @param   pValue:     (IN/OUT)    Pointer to structure or value where
157  *                                  option is stored
158  *
159  * @return  M4NO_ERROR              There is no error
160  * @return  M4ERR_PARAMETER         The context is invalid (in DEBUG only)
161  * @return  M4ERR_BAD_OPTION_ID     When the option ID is not a valid one
162  * @return  M4ERR_STATE             State automaton is not applied
163  * @return  M4ERR_NOT_IMPLEMENTED   Function not implemented
164  ************************************************************************
165 */
M4DECODER_NULL_getOption(M4OSA_Context context,M4OSA_OptionID optionId,M4OSA_DataOption pValue)166 M4OSA_ERR M4DECODER_NULL_getOption(M4OSA_Context context,
167                                    M4OSA_OptionID optionId,
168                                    M4OSA_DataOption  pValue) {
169 
170     return M4ERR_NOT_IMPLEMENTED;
171 }
172 
173 /**
174  ************************************************************************
175  * @brief   Set an option value of the decoder
176  * @note    Allows the caller to set a property value:
177  *
178  * @param   context:    (IN)        Context of the decoder
179  * @param   optionId:   (IN)        Identifier indicating the option to set
180  * @param   pValue:     (IN)        Pointer to structure or value
181  *                                  where option is stored
182  *
183  * @return  M4NO_ERROR              There is no error
184  * @return  M4ERR_BAD_OPTION_ID     The option ID is not a valid one
185  * @return  M4ERR_STATE             State automaton is not applied
186  * @return  M4ERR_PARAMETER         The option parameter is invalid
187  ************************************************************************
188 */
M4DECODER_NULL_setOption(M4OSA_Context context,M4OSA_OptionID optionId,M4OSA_DataOption pValue)189 M4OSA_ERR M4DECODER_NULL_setOption(M4OSA_Context context,
190                                    M4OSA_OptionID optionId,
191                                    M4OSA_DataOption pValue) {
192 
193     M4DECODER_OutputFilter *pFilterOption;
194 
195     M4_VideoHandler_Context *pStreamContext =
196         (M4_VideoHandler_Context*)context;
197 
198     M4OSA_ERR err = M4NO_ERROR;
199     M4OSA_UInt32 height = 0;
200     M4OSA_UInt8 *p_src,*p_des;
201     M4VIFI_ImagePlane* pTempDecYuvData = M4OSA_NULL;
202 
203     switch (optionId) {
204         case M4DECODER_kOptionID_DecYuvData:
205             pStreamContext->pDecYuvData = (M4VIFI_ImagePlane *)pValue;
206             break;
207 
208         case M4DECODER_kOptionID_YuvWithEffectContiguous:
209             pStreamContext->pDecYuvWithEffect = (M4VIFI_ImagePlane *)pValue;
210             break;
211 
212         case M4DECODER_kOptionID_EnableYuvWithEffect:
213             pStreamContext->bYuvWithEffectSet = (M4OSA_Bool)pValue;
214             break;
215 
216         case M4DECODER_kOptionID_YuvWithEffectNonContiguous:
217             pTempDecYuvData =  (M4VIFI_ImagePlane *)pValue;
218 
219             p_des = pStreamContext->pDecYuvWithEffect[0].pac_data +
220                  pStreamContext->pDecYuvWithEffect[0].u_topleft;
221             p_src = pTempDecYuvData[0].pac_data +
222                  pTempDecYuvData[0].u_topleft;
223 
224             for (height = 0; height<pStreamContext->pDecYuvWithEffect[0].u_height;
225              height++) {
226                 memcpy((void *)p_des, (void *)p_src,
227                  pStreamContext->pDecYuvWithEffect[0].u_width);
228 
229                 p_des += pStreamContext->pDecYuvWithEffect[0].u_stride;
230                 p_src += pTempDecYuvData[0].u_stride;
231             }
232 
233             p_des = pStreamContext->pDecYuvWithEffect[1].pac_data +
234              pStreamContext->pDecYuvWithEffect[1].u_topleft;
235             p_src = pTempDecYuvData[1].pac_data +
236              pTempDecYuvData[1].u_topleft;
237 
238             for (height = 0; height<pStreamContext->pDecYuvWithEffect[1].u_height;
239              height++) {
240                 memcpy((void *)p_des, (void *)p_src,
241                  pStreamContext->pDecYuvWithEffect[1].u_width);
242 
243                 p_des += pStreamContext->pDecYuvWithEffect[1].u_stride;
244                 p_src += pTempDecYuvData[1].u_stride;
245             }
246 
247             p_des = pStreamContext->pDecYuvWithEffect[2].pac_data +
248              pStreamContext->pDecYuvWithEffect[2].u_topleft;
249             p_src = pTempDecYuvData[2].pac_data +
250              pTempDecYuvData[2].u_topleft;
251 
252             for (height = 0; height<pStreamContext->pDecYuvWithEffect[2].u_height;
253              height++) {
254                 memcpy((void *)p_des, (void *)p_src,
255                  pStreamContext->pDecYuvWithEffect[2].u_width);
256 
257                 p_des += pStreamContext->pDecYuvWithEffect[2].u_stride;
258                 p_src += pTempDecYuvData[2].u_stride;
259             }
260             break;
261 
262         case M4DECODER_kOptionID_OutputFilter:
263             pFilterOption = (M4DECODER_OutputFilter*)pValue;
264             break;
265 
266         case M4DECODER_kOptionID_DeblockingFilter:
267             err = M4ERR_BAD_OPTION_ID;
268             break;
269 
270         default:
271             err = M4ERR_BAD_OPTION_ID;
272             break;
273     }
274     return err;
275 }
276 
277 /**
278  ************************************************************************
279  * @brief   Decode video Access Units up to a target time
280  * @note    Parse and decode the video until it can output a decoded image
281  *          for which the composition time is equal or greater to the
282  *          passed targeted time.
283  *          The data are read from the reader data interface passed to
284  *          M4DECODER_MPEG4_create.
285  *
286  * @param   context:    (IN)        Context of the decoder
287  * @param   pTime:      (IN/OUT)    IN: Time to decode up to (in msec)
288  *                                  OUT:Time of the last decoded frame (in msec)
289  * @param   bJump:      (IN)        0 if no jump occured just before this call
290  *                                  1 if a a jump has just been made
291  * @return  M4NO_ERROR              there is no error
292  * @return  M4ERR_PARAMETER         at least one parameter is not properly set
293  * @return  M4WAR_NO_MORE_AU        there is no more access unit to decode (EOS)
294  ************************************************************************
295 */
M4DECODER_NULL_decode(M4OSA_Context context,M4_MediaTime * pTime,M4OSA_Bool bJump,M4OSA_UInt32 tolerance)296 M4OSA_ERR M4DECODER_NULL_decode(M4OSA_Context context,
297                                 M4_MediaTime* pTime, M4OSA_Bool bJump,
298                                 M4OSA_UInt32 tolerance) {
299 
300     // Do nothing; input time stamp itself returned
301     return M4NO_ERROR;
302 }
303 
304 /**
305  ************************************************************************
306  * @brief   Renders the video at the specified time.
307  * @note
308  * @param   context:     (IN)       Context of the decoder
309  * @param   pTime:       (IN/OUT)   IN: Time to render to (in msecs)
310  *                                  OUT:Time of the rendered frame (in ms)
311  * @param   pOutputPlane:(OUT)      Output plane filled with decoded data
312  * @param   bForceRender:(IN)       1 if the image must be rendered even it
313  *                                  has been rendered already
314  *                                  0 if not
315  *
316  * @return  M4NO_ERROR              There is no error
317  * @return  M4ERR_PARAMETER         At least one parameter is not properly set
318  * @return  M4ERR_STATE             State automaton is not applied
319  * @return  M4ERR_ALLOC             There is no more available memory
320  * @return  M4WAR_VIDEORENDERER_NO_NEW_FRAME    If the frame has already been rendered
321  ************************************************************************
322 */
M4DECODER_NULL_render(M4OSA_Context context,M4_MediaTime * pTime,M4VIFI_ImagePlane * pOutputPlane,M4OSA_Bool bForceRender)323 M4OSA_ERR M4DECODER_NULL_render(M4OSA_Context context, M4_MediaTime* pTime,
324                                 M4VIFI_ImagePlane* pOutputPlane,
325                                 M4OSA_Bool bForceRender) {
326 
327     M4OSA_ERR err = M4NO_ERROR;
328     M4OSA_UInt32 height;
329     M4OSA_UInt8 *p_src,*p_des;
330     M4_VideoHandler_Context*    pStreamContext =
331         (M4_VideoHandler_Context*)context;
332 
333     if (pStreamContext->bYuvWithEffectSet == M4OSA_TRUE) {
334 
335         p_des = pOutputPlane[0].pac_data + pOutputPlane[0].u_topleft;
336         p_src = pStreamContext->pDecYuvWithEffect[0].pac_data +
337          pStreamContext->pDecYuvWithEffect[0].u_topleft;
338 
339         for (height = 0; height<pOutputPlane[0].u_height; height++) {
340             memcpy((void *)p_des, (void *)p_src, pOutputPlane[0].u_width);
341             p_des += pOutputPlane[0].u_stride;
342             p_src += pStreamContext->pDecYuvWithEffect[0].u_stride;
343         }
344 
345         p_des = pOutputPlane[1].pac_data + pOutputPlane[1].u_topleft;
346         p_src = pStreamContext->pDecYuvWithEffect[1].pac_data +
347          pStreamContext->pDecYuvWithEffect[1].u_topleft;
348 
349         for (height = 0; height<pOutputPlane[1].u_height; height++) {
350             memcpy((void *)p_des, (void *)p_src, pOutputPlane[1].u_width);
351             p_des += pOutputPlane[1].u_stride;
352             p_src += pStreamContext->pDecYuvWithEffect[1].u_stride;
353         }
354 
355         p_des = pOutputPlane[2].pac_data + pOutputPlane[2].u_topleft;
356         p_src = pStreamContext->pDecYuvWithEffect[2].pac_data +
357          pStreamContext->pDecYuvWithEffect[2].u_topleft;
358 
359         for (height = 0; height<pOutputPlane[2].u_height; height++) {
360             memcpy((void *)p_des, (void *)p_src, pOutputPlane[2].u_width);
361             p_des += pOutputPlane[2].u_stride;
362             p_src += pStreamContext->pDecYuvWithEffect[2].u_stride;
363         }
364     } else {
365 
366         p_des = pOutputPlane[0].pac_data + pOutputPlane[0].u_topleft;
367         p_src = pStreamContext->pDecYuvData[0].pac_data +
368          pStreamContext->pDecYuvData[0].u_topleft;
369 
370         for (height = 0; height<pOutputPlane[0].u_height; height++) {
371             memcpy((void *)p_des, (void *)p_src, pOutputPlane[0].u_width);
372             p_des += pOutputPlane[0].u_stride;
373             p_src += pStreamContext->pDecYuvData[0].u_stride;
374         }
375 
376         p_des = pOutputPlane[1].pac_data + pOutputPlane[1].u_topleft;
377         p_src = pStreamContext->pDecYuvData[1].pac_data +
378          pStreamContext->pDecYuvData[1].u_topleft;
379 
380         for (height = 0; height<pOutputPlane[1].u_height; height++) {
381             memcpy((void *)p_des, (void *)p_src, pOutputPlane[1].u_width);
382             p_des += pOutputPlane[1].u_stride;
383             p_src += pStreamContext->pDecYuvData[1].u_stride;
384         }
385 
386         p_des = pOutputPlane[2].pac_data + pOutputPlane[2].u_topleft;
387         p_src = pStreamContext->pDecYuvData[2].pac_data +
388          pStreamContext->pDecYuvData[2].u_topleft;
389 
390         for (height = 0; height<pOutputPlane[2].u_height; height++) {
391             memcpy((void *)p_des,(void *)p_src,pOutputPlane[2].u_width);
392             p_des += pOutputPlane[2].u_stride;
393             p_src += pStreamContext->pDecYuvData[2].u_stride;
394         }
395     }
396     return err;
397 }
398 
399 /**
400  ************************************************************************
401  * @brief Retrieves the interface implemented by the decoder
402  * @param pDecoderType        : Pointer to a M4DECODER_VideoType
403  *                             (allocated by the caller)
404  *                             that will be filled with the decoder type
405  * @param pDecoderInterface   : Address of a pointer that will be set to
406  *                              the interface implemented by this decoder.
407  *                              The interface is a structure allocated by
408  *                              this function and must be freed by the caller.
409  *
410  * @returns : M4NO_ERROR  if OK
411  *            M4ERR_ALLOC if allocation failed
412  ************************************************************************
413 */
M4DECODER_NULL_getInterface(M4DECODER_VideoType * pDecoderType,M4DECODER_VideoInterface ** pDecoderInterface)414 M4OSA_ERR M4DECODER_NULL_getInterface (M4DECODER_VideoType *pDecoderType,
415                             M4DECODER_VideoInterface **pDecoderInterface) {
416 
417     *pDecoderInterface =
418         (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc(
419          sizeof(M4DECODER_VideoInterface),
420          M4DECODER_MPEG4, (M4OSA_Char *)"M4DECODER_VideoInterface");
421 
422     if (M4OSA_NULL == *pDecoderInterface) {
423         return M4ERR_ALLOC;
424     }
425 
426     *pDecoderType = M4DECODER_kVideoTypeYUV420P;
427 
428     (*pDecoderInterface)->m_pFctCreate    = M4DECODER_NULL_create;
429     (*pDecoderInterface)->m_pFctDestroy   = M4DECODER_NULL_destroy;
430     (*pDecoderInterface)->m_pFctGetOption = M4DECODER_NULL_getOption;
431     (*pDecoderInterface)->m_pFctSetOption = M4DECODER_NULL_setOption;
432     (*pDecoderInterface)->m_pFctDecode    = M4DECODER_NULL_decode;
433     (*pDecoderInterface)->m_pFctRender    = M4DECODER_NULL_render;
434 
435     return M4NO_ERROR;
436 }
437