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#include <jni.h>
19#include <JNIHelp.h>
20#include <utils/Log.h>
21#include "VideoBrowserMain.h"
22#include "VideoBrowserInternal.h"
23
24#if (M4OSA_TRACE_LEVEL >= 1)
25#undef M4OSA_TRACE1_0
26#undef M4OSA_TRACE1_1
27#undef M4OSA_TRACE1_2
28#undef M4OSA_TRACE1_3
29
30#define M4OSA_TRACE1_0(a)       __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a);
31#define M4OSA_TRACE1_1(a,b)     __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b);
32#define M4OSA_TRACE1_2(a,b,c)   __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c);
33#define M4OSA_TRACE1_3(a,b,c,d) __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c,d);
34#endif
35
36/*
37 * Memory format of 'ARGB8888' in skia is RGBA, so ABGR in 32bit little-endian packed format
38 * bitmap format is rgb565
39 */
40//                                RED                 GREEN               BLUE            ALPHA
41#define RGB565toSKCOLOR(c) ( (((c)&0xF800)>>8) | (((c)&0x7E0)<<5) | (((c)&0x1F)<<19) | 0xFF000000)
42
43#define GetIntField(env, obj, name) env->GetIntField(obj,\
44env->GetFieldID(env->GetObjectClass(obj), name, "I"))
45
46extern "C" M4OSA_ERR NXPSW_FileReaderOptim_init(M4OSA_Void *lowLevel_functionPointers,
47        M4OSA_Void *optimized_functionPointers);
48
49/*
50 * Video Browser execution context.
51 * Based on request for RGB565 or RGB888, m_dst16 or m_dst32
52 * will be initialized and used
53 */
54typedef struct
55{
56    M4OSA_Context       m_pVideoBrowser;
57    M4OSA_UInt32        m_previousTime;
58    M4OSA_Int32*        m_dst32;
59    M4OSA_Int16*        m_dst16;
60    unsigned int        m_width;
61    unsigned int        m_height;
62    M4OSA_Bool          m_bRender;
63} ThumbnailContext;
64
65/**
66 ************************************************************************
67 * @brief    Interface to retrieve the thumbnail pixels
68 * @param    pContext   (IN)    Thumbnail Context.
69 * @param    width      (IN)    Width of thumbnail
70 * @param    height     (IN)    Height of thumbnail
71 * @param    pTimeMS    (IN/OUT)Time stamp at which thumbnail is retrieved.
72 ************************************************************************
73*/
74M4OSA_ERR ThumbnailGetPixels(const M4OSA_Context pContext,
75                             M4OSA_Int32* pixelArray,
76                             M4OSA_UInt32 width, M4OSA_UInt32 height,
77                             M4OSA_UInt32* pTimeMS, M4OSA_UInt32 tolerance);
78
79
80/**
81 ************************************************************************
82 * @brief    Video browser callback, called when a frame must be displayed
83 * @param    pInstance          (IN) Thumbnail context.
84 * @param    notificationID     (IN) Id of the callback which generated the error
85 * @param    errCode            (IN) Error code from the Core
86 * @param    pCbData            (IN) pointer to data associated wit the callback.
87 * @param    pCbUserData        (IN) pointer to application user data passed in init.
88 * @note     This callback mechanism is used to request display of an image
89 ************************************************************************
90*/
91M4OSA_Void VBcallback(  M4OSA_Context  pInstance,
92                        VideoBrowser_Notification notificationID,
93                        M4OSA_ERR errCode, M4OSA_Void* pCbData,
94                        M4OSA_Void* pCallbackUserData)
95{
96    M4OSA_UInt32 i, j;
97    M4OSA_ERR err;
98
99    M4OSA_TRACE3_0("inside VBcallback");
100    M4VIFI_ImagePlane* pPlane=NULL;
101    M4OSA_UInt16* src=NULL;
102    ThumbnailContext* pC = NULL;
103
104    CHECK_PTR(VBcallback, pCbData, err, M4ERR_PARAMETER);
105    CHECK_PTR(VBcallback, pInstance,err, M4ERR_PARAMETER);
106
107    pC = (ThumbnailContext*)pCallbackUserData ;
108    CHECK_PTR(VBcallback, pC->m_pVideoBrowser, err, M4ERR_PARAMETER);
109
110    pPlane = (M4VIFI_ImagePlane*)pCbData;
111    src = (M4OSA_UInt16*)pPlane->pac_data;
112
113    if (pC->m_dst32 != NULL)
114    {
115        M4OSA_Int32* dst = pC->m_dst32;
116
117        for (j = 0; j < pPlane->u_height; j++)
118        {
119            for (i = 0; i < pPlane->u_width; i++)
120            {
121                dst[i] = RGB565toSKCOLOR(src[i]);
122            }
123            for (i = pPlane->u_width; i < pC->m_width; i++)
124            {
125                dst[i] = 0;
126            }
127            src = (M4OSA_UInt16*)((M4OSA_UInt8*)src + pPlane->u_stride);
128            dst += pC->m_width;
129        }
130    }
131    else if (pC->m_dst16 != NULL)
132    {
133        M4OSA_Int16* dst = pC->m_dst16;
134
135        for (j = 0; j < pPlane->u_height; j++)
136        {
137            memcpy((void * )dst, (void * )src, pPlane->u_stride);
138            for (i = pPlane->u_width; i < pC->m_width; i++)
139            {
140                dst[i] = 0;
141            }
142            src = (M4OSA_UInt16*)((M4OSA_UInt8*)src + pPlane->u_stride);
143            dst += pC->m_width;
144        }
145    }
146    else
147    {
148        CHECK_PTR(VBcallback, NULL, err, M4ERR_PARAMETER);
149    }
150
151VBcallback_cleanUp:
152
153    return;
154}
155
156M4OSA_ERR ThumbnailOpen(M4OSA_Context *pPContext,
157                  const M4OSA_Char *pString,
158                  M4OSA_Bool bRender)
159{
160
161    M4OSA_ERR err;
162    ThumbnailContext *pContext = M4OSA_NULL;
163    VideoBrowser_VideoColorType vbColorType;
164
165    CHECK_PTR(ThumbnailOpen, pString, err, M4ERR_BAD_CONTEXT);
166
167    /*--- Create context ---*/
168    pContext = (ThumbnailContext*)M4OSA_32bitAlignedMalloc(sizeof(ThumbnailContext), VIDEOBROWSER,
169        (M4OSA_Char*)"Thumbnail context") ;
170    M4OSA_TRACE3_1("context value is = %d",pContext);
171    CHECK_PTR(ThumbnailOpen, pContext, err, M4ERR_ALLOC);
172
173    memset((void *)pContext, 0,sizeof(ThumbnailContext));
174
175    M4OSA_FileReadPointer optFP;
176    M4OSA_FileReadPointer llFP;
177
178    NXPSW_FileReaderOptim_init(&llFP, &optFP);
179    M4OSA_TRACE1_2("ThumbnailOpen: entering videoBrowserCreate with 0x%x %s",
180        &pContext->m_pVideoBrowser, pString) ;
181
182    pContext->m_bRender = bRender;
183    if (bRender == M4OSA_TRUE) {
184        //Open is called for rendering the frame.
185        //So set YUV420 as the output color format.
186        vbColorType = VideoBrowser_kYUV420;
187    } else {
188        //Open is called for thumbnail Extraction
189        //So set BGR565 as the output.
190        vbColorType = VideoBrowser_kGB565;
191    }
192
193    err = videoBrowserCreate(&pContext->m_pVideoBrowser, (M4OSA_Char*)pString,
194        VideoBrowser_kVBNormalBliting, &optFP, VBcallback, pContext, vbColorType);
195
196    M4OSA_TRACE1_1("err value is = 0x%x",err);
197    CHECK_ERR(ThumbnailOpen, err);
198    CHECK_PTR(ThumbnailOpen, pContext->m_pVideoBrowser, err, M4ERR_ALLOC);
199
200    *pPContext = pContext;
201    M4OSA_TRACE1_1("context value is = %d",*pPContext);
202
203    return M4NO_ERROR;
204
205ThumbnailOpen_cleanUp:
206
207    M4OSA_TRACE1_0("i am inside cleanUP");
208    if (M4OSA_NULL != pContext)
209    {
210        if (M4OSA_NULL != pContext->m_pVideoBrowser)
211        {
212            videoBrowserCleanUp(pContext->m_pVideoBrowser) ;
213        }
214        free(pContext) ;
215    }
216    return err;
217}
218
219M4OSA_ERR ThumbnailGetPixels(const M4OSA_Context pContext,
220                             M4OSA_Int32* pixelArray,
221                             M4OSA_UInt32 width, M4OSA_UInt32 height,
222                             M4OSA_UInt32* pTimeMS, M4OSA_UInt32 tolerance)
223{
224    M4OSA_ERR err;
225
226    ThumbnailContext* pC = (ThumbnailContext*)pContext;
227
228    if ((pC->m_width != width) || (pC->m_height != height))
229    {
230        err = videoBrowserSetWindow(pC->m_pVideoBrowser, pixelArray,
231                                      0, 0, width, height);
232        CHECK_ERR(ThumbnailGetPixels, err);
233        pC->m_width  = width;
234        pC->m_height = height;
235    }
236
237    // Alter the pTimeMS to a valid value at which a frame is found
238    // m_currentCTS has the actual frame time stamp just ahead of the
239    // pTimeMS supplied.
240    if ((((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS != 0) &&
241        (*pTimeMS >= pC->m_previousTime) &&
242        (*pTimeMS < ((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS))
243    {
244        pC->m_previousTime = *pTimeMS;
245        *pTimeMS = ((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS;
246    }
247    else
248    {
249        pC->m_previousTime = *pTimeMS;
250    }
251
252    err = videoBrowserPrepareFrame(pC->m_pVideoBrowser, pTimeMS, tolerance);
253    CHECK_ERR(ThumbnailGetPixels, err);
254
255    if (pC->m_bRender != M4OSA_TRUE) {
256        err = videoBrowserDisplayCurrentFrame(pC->m_pVideoBrowser);
257        CHECK_ERR(ThumbnailGetPixels, err);
258    }
259
260ThumbnailGetPixels_cleanUp:
261
262    return err;
263}
264
265M4OSA_ERR ThumbnailGetPixels32(const M4OSA_Context pContext,
266                         M4OSA_Int32* pixelArray, M4OSA_UInt32 width,
267                         M4OSA_UInt32 height, M4OSA_UInt32* timeMS,
268                         M4OSA_UInt32 tolerance)
269{
270
271    M4OSA_ERR err = M4NO_ERROR;
272
273    ThumbnailContext* pC = (ThumbnailContext*)pContext;
274
275    CHECK_PTR(ThumbnailGetPixels32, pC->m_pVideoBrowser, err, M4ERR_ALLOC) ;
276    CHECK_PTR(ThumbnailGetPixels32, pixelArray, err, M4ERR_ALLOC) ;
277
278    pC->m_dst16 = NULL;
279    pC->m_dst32 = pixelArray;
280
281    err = ThumbnailGetPixels(pContext, pixelArray, width, height, timeMS, tolerance);
282
283ThumbnailGetPixels32_cleanUp:
284
285    return err;
286}
287
288M4OSA_ERR ThumbnailGetPixels16(const M4OSA_Context pContext,
289                         M4OSA_Int16* pixelArray, M4OSA_UInt32 width,
290                         M4OSA_UInt32 height, M4OSA_UInt32* timeMS,
291                         M4OSA_UInt32 tolerance)
292{
293    M4OSA_ERR err = M4NO_ERROR;
294
295    ThumbnailContext* pC = (ThumbnailContext*)pContext;
296
297    CHECK_PTR(ThumbnailGetPixels16, pC->m_pVideoBrowser, err, M4ERR_ALLOC);
298    CHECK_PTR(ThumbnailGetPixels16, pixelArray, err, M4ERR_ALLOC);
299
300    pC->m_dst16 = pixelArray;
301    pC->m_dst32 = NULL;
302
303    err = ThumbnailGetPixels(pContext, (M4OSA_Int32*)pixelArray, width, height,
304            timeMS, tolerance);
305
306ThumbnailGetPixels16_cleanUp:
307
308    return err;
309}
310
311
312void ThumbnailClose(const M4OSA_Context pContext)
313{
314    M4OSA_ERR err;
315
316    ThumbnailContext* pC = (ThumbnailContext*)pContext;
317
318    CHECK_PTR(ThumbnailClose, pC, err, M4ERR_ALLOC);
319
320    if (M4OSA_NULL != pC)
321    {
322        if (M4OSA_NULL != pC->m_pVideoBrowser)
323        {
324            videoBrowserCleanUp(pC->m_pVideoBrowser);
325        }
326        free(pC);
327    }
328
329ThumbnailClose_cleanUp:
330
331    return;
332}
333
334