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 */ 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 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 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 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 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 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