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,\
44 env->GetFieldID(env->GetObjectClass(obj), name, "I"))
45
46 extern "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 */
54 typedef 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 */
74 M4OSA_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 */
VBcallback(M4OSA_Context pInstance,VideoBrowser_Notification notificationID,M4OSA_ERR errCode,M4OSA_Void * pCbData,M4OSA_Void * pCallbackUserData)91 M4OSA_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
151 VBcallback_cleanUp:
152
153 return;
154 }
155
ThumbnailOpen(M4OSA_Context * pPContext,const M4OSA_Char * pString,M4OSA_Bool bRender)156 M4OSA_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
205 ThumbnailOpen_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
ThumbnailGetPixels(const M4OSA_Context pContext,M4OSA_Int32 * pixelArray,M4OSA_UInt32 width,M4OSA_UInt32 height,M4OSA_UInt32 * pTimeMS,M4OSA_UInt32 tolerance)219 M4OSA_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
260 ThumbnailGetPixels_cleanUp:
261
262 return err;
263 }
264
ThumbnailGetPixels32(const M4OSA_Context pContext,M4OSA_Int32 * pixelArray,M4OSA_UInt32 width,M4OSA_UInt32 height,M4OSA_UInt32 * timeMS,M4OSA_UInt32 tolerance)265 M4OSA_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
283 ThumbnailGetPixels32_cleanUp:
284
285 return err;
286 }
287
ThumbnailGetPixels16(const M4OSA_Context pContext,M4OSA_Int16 * pixelArray,M4OSA_UInt32 width,M4OSA_UInt32 height,M4OSA_UInt32 * timeMS,M4OSA_UInt32 tolerance)288 M4OSA_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
306 ThumbnailGetPixels16_cleanUp:
307
308 return err;
309 }
310
311
ThumbnailClose(const M4OSA_Context pContext)312 void 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
329 ThumbnailClose_cleanUp:
330
331 return;
332 }
333
334