FREObject saveToCameraRoll(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { uint32_t name_size = 0; const uint8_t* name_val = NULL; FREGetObjectAsUTF8(argv[0], &name_size, &name_val); FREObject objectBA = argv[1]; FREByteArray baData; FREAcquireByteArray(objectBA, &baData); uint8_t *ba = baData.bytes; int32_t _size; FREGetObjectAsInt32(argv[2], &_size); int32_t _orientation; FREGetObjectAsInt32(argv[3], &_orientation); int32_t res = captureSaveToCameraRoll( (const char *)name_val, (const uint8_t*)ba, _size, _orientation); FREReleaseByteArray(objectBA); FREObject res_obj; FRENewObjectFromInt32(res, &res_obj); return res_obj; }
FREObject KinectDevice::freGetPointCloudFrame(FREObject argv[]) { FREObject objectPointsByteArray = argv[1]; const unsigned int numPointBytes = pointCloudGenerator->getByteArrayLength() * sizeof(short); if(numPointBytes == 0) return NULL; lockPointCloudMutex(); FREByteArray pointsByteArray; FREObject pointsLength; FRENewObjectFromUint32(numPointBytes, &pointsLength); FRESetObjectProperty(objectPointsByteArray, (const uint8_t*) "length", pointsLength, NULL); FREAcquireByteArray(objectPointsByteArray, &pointsByteArray); memcpy(pointsByteArray.bytes, pointCloudGenerator->getTargetBytes(), numPointBytes); FREReleaseByteArray(objectPointsByteArray); //set the region information? FREObject asPointCloudRegions = argv[2]; if(asPointCloudRegions != NULL && &pointCloudRegions != 0) { //loop through these actionscript regions and get the native info back FREObject asPointCloudRegion, asRegionId; FREObject asNumPoints; unsigned int regionId; uint32_t freNumRegions; FREGetArrayLength(asPointCloudRegions, &freNumRegions); for(unsigned int i = 0; i < freNumRegions; i++) { FREGetArrayElementAt(asPointCloudRegions, i, &asPointCloudRegion); FREGetObjectProperty(asPointCloudRegion, (const uint8_t *) "regionId", &asRegionId, NULL); FREGetObjectAsUint32(asRegionId, ®ionId); //get the region with this id from the device memory for(unsigned int j = 0; j < numRegions; j++) { PointCloudRegion *nativeRegion = &pointCloudRegions[j]; if(nativeRegion->regionId == regionId) { //update the actionscript properties FRENewObjectFromUint32(nativeRegion->numPoints, &asNumPoints); FRESetObjectProperty(asPointCloudRegion, (const uint8_t *) "numPoints", asNumPoints, NULL); break; } } } } unlockPointCloudMutex(); return NULL; }
FREObject KinectDevice::freGetInfraredFrame(FREObject argv[]) { const unsigned int numInfraredBytes = infraredImageBytesGenerator->getTargetPixelCount() * 4; FREObject objectByteArray = argv[1]; FREByteArray byteArray; FREObject length; FRENewObjectFromUint32(numInfraredBytes, &length); FRESetObjectProperty(objectByteArray, (const uint8_t*) "length", length, NULL); FREAcquireByteArray(objectByteArray, &byteArray); lockInfraredMutex(); memcpy(byteArray.bytes, infraredImageBytesGenerator->getTargetBytes(), numInfraredBytes); unlockInfraredMutex(); FREReleaseByteArray(objectByteArray); return NULL; }
FREObject getBytesAsByteArray(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { FREObject result; FREByteArray incomingBytes; FREAcquireByteArray(argv[0], &incomingBytes); pthread_mutex_lock(&safety); memcpy(incomingBytes.bytes, buffer, bufferSize); FRENewObjectFromInt32(bufferSize, &result); bufferSize = 0; sentEvent = 0; pthread_mutex_unlock(&safety); FREReleaseByteArray(&incomingBytes); return result; }
FREObject KinectDevice::freGetUserMaskFrame(FREObject argv[]) { unsigned int trackingID; FREGetObjectAsUint32(argv[1], &trackingID); if(trackingID > 0) trackingID--; const unsigned int numUserMaskBytes = userMasksGenerator->getTargetPixelCount() * 4; FREObject objectByteArray = argv[2]; FREByteArray byteArray; FREObject length; FRENewObjectFromUint32(numUserMaskBytes, &length); FRESetObjectProperty(objectByteArray, (const uint8_t*) "length", length, NULL); FREAcquireByteArray(objectByteArray, &byteArray); lockUserMaskMutex(); memcpy(byteArray.bytes, userMasksGenerator->getTargetBytes()[trackingID], numUserMaskBytes); unlockUserMaskMutex(); FREReleaseByteArray(objectByteArray); return NULL; }
FREObject sendByteArray(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { FREObject result; FREByteArray dataToSend; int sendResult = 0; FREAcquireByteArray(argv[0], &dataToSend); sendResult = SendBuf(comPort, (unsigned char *)&dataToSend.bytes, dataToSend.length); FREReleaseByteArray(argv[0]); if (sendResult == -1) { FRENewObjectFromBool(0, &result); } else { FRENewObjectFromBool(1, &result); } return result; }
FREObject listDevices(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { int32_t i, numDevices = 0; CaptureDeviceInfo devices[MAX_ACTIVE_CAMS * 2]; int32_t refresh = 0; FREGetObjectAsInt32(argv[0], &refresh); numDevices = getCaptureDevices(devices, refresh); FREObject objectBA = argv[1]; FREByteArray baData; FREAcquireByteArray(objectBA, &baData); uint8_t *ba = baData.bytes; ba += ba_write_int(ba, numDevices); for (i = 0; i < numDevices; i++) { const CaptureDeviceInfo *dev = &devices[i]; ba += ba_write_int(ba, dev->name_size); memcpy( ba, (uint8_t*)dev->name, dev->name_size ); ba += dev->name_size; ba += ba_write_int(ba, dev->available); ba += ba_write_int(ba, dev->connected); //printf("device (%d): %s \n", i, dev->name); } FREReleaseByteArray(objectBA); return NULL; }
FREObject grabCamShot(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { if(_cam_shot_data) { FREObject length = NULL; FRENewObjectFromUint32(_cam_shot_size, &length); FRESetObjectProperty(argv[0], (const uint8_t*) "length", length, NULL); FREObject objectBA = argv[0]; FREByteArray baData; FREAcquireByteArray(objectBA, &baData); uint8_t *ba = baData.bytes; memcpy(ba, _cam_shot_data, _cam_shot_size); FREReleaseByteArray(objectBA); free(_cam_shot_data); _cam_shot_size = 0; _cam_shot_data = NULL; } return NULL; }
FREObject getCaptureFrame(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { int32_t _id, _opt; FREGetObjectAsInt32(argv[0], &_id); FREObject res_obj; FRENewObjectFromInt32(0, &res_obj); FREObject objectBA; FREByteArray baData; FREBitmapData2 bitmapData; uint8_t *ba; const uint8_t* frame_0; const uint8_t* frame; int32_t w, h, w2, h2, widthInBytes, i, j; uint32_t fstride; CCapture* cap; cap = active_cams[_id]; uint32_t flipped = 0; uint32_t isWin = 1; #if defined(ANE_MAC) isWin = 0; #endif objectBA = argv[1]; FREAcquireByteArray(objectBA, &baData); ba = baData.bytes; ba += ba_read_int(ba, &_opt); ba += ba_read_int(ba, &w2); ba += ba_read_int(ba, &h2); FREReleaseByteArray(objectBA); if(cap && captureCheckNewFrame(cap)) { frame_0 = (const uint8_t*)captureGetFrame(cap, &w, &h, &widthInBytes); // here is some conversion we need cause in Flash BitmapData bytes // represented differently :( if((_opt & FRAME_BITMAP)) { objectBA = argv[2]; FREAcquireBitmapData2(objectBA, &bitmapData); uint32_t* input = bitmapData.bits32; fstride = bitmapData.lineStride32 * sizeof(uint32_t); // for some reasons not always == width flipped = bitmapData.isInvertedY; frame = frame_0; ba = (uint8_t*)input; #if defined (__ANDROID__) || defined (ANE_IOS) for(i=0; i<h; i++){ memcpy(ba+i*fstride, frame+i*widthInBytes, fstride); } #else // most likely wont happen / but who knows? ;) if(flipped && !isWin) { const uint8_t* a_ptr = (const uint8_t*)frame; const uint8_t* a_ptr2 = (const uint8_t*)(frame + (h - 1) * widthInBytes); uint8_t* b_ptr = ba + (h - 1) * fstride; uint8_t* b_ptr2 = ba; for(i = 0; i < h / 2; i++) { uint8_t *ba_ln = b_ptr; uint8_t *ba_ln2 = b_ptr2; const uint8_t *a_ln = a_ptr; const uint8_t *a_ln2 = a_ptr2; #if defined(ANE_MSW) for(j = 0; j < w; j++, ba_ln += 4, ba_ln2 += 4, a_ln += 3, a_ln2 += 3) { *ba_ln = *(a_ln); ba_ln[1] = *(a_ln+1); ba_ln[2] = *(a_ln+2); // *ba_ln2 = *(a_ln2); ba_ln2[1] = *(a_ln2+1); ba_ln2[2] = *(a_ln2+2); } #elif defined(ANE_MAC) memcpy(ba_ln, a_ln, widthInBytes); memcpy(ba_ln2, a_ln2, widthInBytes); #endif a_ptr += widthInBytes; a_ptr2 -= widthInBytes; b_ptr -= fstride; b_ptr2 += fstride; } if(h&1) { #if defined(ANE_MSW) for(j = 0; j < w; j++, b_ptr += 4, a_ptr+=3) { *b_ptr = *(a_ptr); b_ptr[1] = *(a_ptr+1); b_ptr[2] = *(a_ptr+2); } #elif defined(ANE_MAC) memcpy(b_ptr, a_ptr, widthInBytes); #endif } } else { for(i = 0; i < h; i++) { uint8_t *ba_ln = ba; const uint8_t *fr_ln = frame; #if defined(ANE_MSW) for(j = 0; j < w; j++, ba_ln += 4, fr_ln += 3) { *ba_ln = *(fr_ln); ba_ln[1] = *(fr_ln+1); ba_ln[2] = *(fr_ln+2); } #elif defined(ANE_MAC) memcpy(ba_ln, fr_ln, widthInBytes); #endif ba += fstride; frame += widthInBytes; } } #endif FREReleaseBitmapData(objectBA); } if((_opt & FRAME_RAW)) { objectBA = argv[3]; FREAcquireByteArray(objectBA, &baData); ba = baData.bytes; memcpy(ba, frame_0, widthInBytes * h); FREReleaseByteArray(objectBA); } // power of 2 output for stage3d if((_opt & FRAME_P2_BGRA)) { objectBA = argv[4]; FREAcquireByteArray(objectBA, &baData); ba = baData.bytes; frame = frame_0; // resize /* if(w > w2 || h > h2) { float scx = (float)w2 / (float)w; float scy = (float)h2 / (float)h; if(scy < scx) scx = scy; int32_t wr = w * scx; int32_t hr = h * scx; uint8_t *frame_rs = allocResizeBuf(wr, hr, 4); //resample_area_8u(frame, w, h, frame_rs, wr, hr, 4); // update values w = wr; h = hr; frame = frame_rs; widthInBytes = wr * sizeof(uint32_t); } */ int32_t p2w = (w2); int32_t p2h = (h2); int32_t off_x = (p2w - w) / 2; // -64 int32_t off_y = (p2h - h) / 2; size_t p2stride = p2w * sizeof(uint32_t); int32_t b_off_x, b_off_y, a_off_x, a_off_y; if(off_x < 0) { b_off_x = 0; a_off_x = -off_x; } else { b_off_x = off_x; a_off_x = 0; } if(off_y < 0) { b_off_y = 0; a_off_y = -off_y; } else { b_off_y = off_y; a_off_y = 0; } uint8_t* b_ptr0 = ba + b_off_y * p2stride + b_off_x*4; int32_t nw = w - a_off_x*2; int32_t nh = h - a_off_y*2; #if defined (ANE_MSW) // we need flip Y const uint8_t* a_ptr0 = (const uint8_t*)(frame + a_off_y * widthInBytes + a_off_x*3); const uint8_t* a_ptr = a_ptr0; const uint8_t* a_ptr2 = a_ptr0 + (nh - 1) * widthInBytes; uint8_t* b_ptr = b_ptr0 + (h - 1) * p2stride; uint8_t* b_ptr2 = b_ptr0; const uint8_t alpha = 0xFF; for(i = 0; i < nh / 2; i++) { uint8_t *ba_ln = b_ptr; uint8_t *ba_ln2 = b_ptr2; const uint8_t *a_ln = a_ptr; const uint8_t *a_ln2 = a_ptr2; for(j = 0; j < nw; j++, ba_ln += 4, ba_ln2 += 4, a_ln += 3, a_ln2 += 3) { *ba_ln = *(a_ln+0); ba_ln[1] = *(a_ln+1); ba_ln[2] = *(a_ln+2); ba_ln[3] = alpha; // *ba_ln2 = *(a_ln2+0); ba_ln2[1] = *(a_ln2+1); ba_ln2[2] = *(a_ln2+2); ba_ln2[3] = alpha; } a_ptr += widthInBytes; a_ptr2 -= widthInBytes; b_ptr -= p2stride; b_ptr2 += p2stride; } if(nh&1) { for(j = 0; j < nw; j++, b_ptr += 4, a_ptr+=3) { *b_ptr = *(a_ptr+0); b_ptr[1] = *(a_ptr+1); b_ptr[2] = *(a_ptr+2); b_ptr[3] = alpha; } } #elif defined(ANE_MAC) || defined (ANE_IOS) || defined (__ANDROID__) const uint8_t* a_ptr0 = (const uint8_t*)(frame + a_off_y * widthInBytes + a_off_x*4); for(i = 0; i < nh; i++) { memcpy(b_ptr0, a_ptr0, nw*4); a_ptr0 += widthInBytes; b_ptr0 += p2stride; } #endif FREReleaseByteArray(objectBA); } FRENewObjectFromInt32(1, &res_obj); } else if(cap) { // lets see if device is available it may be freezed if( captureCheckResponse(cap) == 0 ) { FRENewObjectFromInt32(-1, &res_obj); } } return res_obj; }
FREObject getCapture(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { int32_t w, h; int32_t frameRate = 0; uint32_t name_size = 0; const uint8_t* name_val = NULL; FREGetObjectAsUTF8(argv[0], &name_size, &name_val); FREGetObjectAsInt32(argv[1], &w); FREGetObjectAsInt32(argv[2], &h); FREGetObjectAsInt32(argv[3], &frameRate); FREObject objectBA = argv[4]; FREByteArray baData; FREAcquireByteArray(objectBA, &baData); uint8_t *ba = baData.bytes; int32_t emptySlot = -1; size_t i; // search empty slot for(i = 0; i < MAX_ACTIVE_CAMS; i++) { if(!active_cams[i]) { emptySlot = i; break; } } if(emptySlot == -1) { ba += ba_write_int(ba, -1); FREReleaseByteArray(objectBA); return NULL; } CCapture* cap = NULL; cap = createCameraCapture(w, h, (char *)name_val, frameRate ); if(!cap) { ba += ba_write_int(ba, -1); FREReleaseByteArray(objectBA); return NULL; } // start if not running if( captureIsCapturing(cap) == 0 ) { captureStart(cap); } active_cams[emptySlot] = cap; active_cams_count++; captureGetSize( cap, &w, &h ); // write result ba += ba_write_int(ba, emptySlot); ba += ba_write_int(ba, w); ba += ba_write_int(ba, h); FREReleaseByteArray(objectBA); return NULL; }