int prepare_g2d(int instns) { int i; for (i = 0; i < g_num_buffers; i++) { #if CACHEABLE ins_priv[instns].g2d_buffers[i] = g2d_alloc(g_frame_size, 1);//alloc physical contiguous memory for source image data with cacheable attribute #else ins_priv[instns].g2d_buffers[i] = g2d_alloc(g_frame_size, 0);//alloc physical contiguous memory for source image data #endif if(!ins_priv[instns].g2d_buffers[i]) { printf("Fail to allocate physical memory for image buffer!\n"); return -1; } //printf("g2d_buffers[%d].buf_paddr = 0x%x.\r\n", i, g2d_buffers[i]->buf_paddr); } return 0; }
int _IOGetPhyMem(int which, vpu_mem_desc *buff) { #ifdef BUILD_FOR_ANDROID const size_t pagesize = getpagesize(); int err, fd; #ifdef USE_ION #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) ion_user_handle_t handle; #else struct ion_handle *handle; #endif int share_fd, ret = -1; unsigned char *ptr; #elif USE_GPU struct g2d_buf *gbuf; int bytes; #else /* Get memory from pmem space for android */ struct pmem_region region; #endif if ((!buff) || (!buff->size)) { err_msg("Error!_IOGetPhyMem:Invalid parameters"); return -1; } buff->cpu_addr = 0; buff->phy_addr = 0; buff->virt_uaddr = 0; if (which == VPU_IOC_GET_WORK_ADDR) { if (ioctl(vpu_fd, which, buff) < 0) { err_msg("mem allocation failed!\n"); buff->phy_addr = 0; buff->cpu_addr = 0; return -1; } return 0; } if (which != VPU_IOC_PHYMEM_ALLOC) { err_msg("Error!_IOGetPhyMem unsupported memtype: %d", which); return -1; } buff->size = (buff->size + pagesize-1) & ~(pagesize - 1); #ifdef USE_ION fd = ion_open(); if (fd <= 0) { err_msg("ion open failed!\n"); return -1; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) err = ion_alloc(fd, buff->size, pagesize, 1, 0, &handle); #else err = ion_alloc(fd, buff->size, pagesize, 1, &handle); #endif if (err) { err_msg("ion allocation failed!\n"); goto error; } err = ion_map(fd, handle, buff->size, PROT_READ|PROT_WRITE, MAP_SHARED, 0, &ptr, &share_fd); if (err) { err_msg("ion map failed!\n"); goto error; } err = ion_phys(fd, handle); if (err == 0) { err_msg("ion get physical address failed!\n"); goto error; } buff->virt_uaddr = (unsigned long)ptr; buff->phy_addr = (unsigned long)err; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) ion_free(fd, handle); buff->cpu_addr = (unsigned long)share_fd; #else buff->cpu_addr = (unsigned long)handle; #endif memset((void*)buff->virt_uaddr, 0, buff->size); ret = 0; info_msg("<ion> alloc handle: 0x%x, paddr: 0x%x, vaddr: 0x%x", (unsigned int)handle, (unsigned int)buff->phy_addr, (unsigned int)buff->virt_uaddr); error: #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) close(share_fd); #endif ion_close(fd); return ret; #elif USE_GPU bytes = buff->size + PAGE_SIZE; gbuf = g2d_alloc(bytes, 0); if(!gbuf) { err_msg("%s: gpu allocator failed to alloc buffer with size %d", __FUNCTION__, buff->size); return -1; } buff->virt_uaddr = (unsigned long)gbuf->buf_vaddr; buff->phy_addr = (unsigned long)gbuf->buf_paddr; buff->cpu_addr = (unsigned long)gbuf; //vpu requires page alignment for the address implicitly, round it to page edge buff->virt_uaddr = (buff->virt_uaddr + PAGE_SIZE -1) & ~(PAGE_SIZE -1); buff->phy_addr = (buff->phy_addr + PAGE_SIZE -1) & ~(PAGE_SIZE -1); memset((void*)buff->virt_uaddr, 0, buff->size); info_msg("<gpu> alloc handle: 0x%x, paddr: 0x%x, vaddr: 0x%x", (unsigned int)gbuf, (unsigned int)buff->phy_addr, (unsigned int)buff->virt_uaddr); return 0; #else fd = (unsigned long)open("/dev/pmem_adsp", O_RDWR | O_SYNC); if (fd < 0) { err_msg("Error!_IOGetPhyMem Error,cannot open pmem"); return -1; } err = ioctl(fd, PMEM_GET_TOTAL_SIZE, ®ion); buff->virt_uaddr = (unsigned long)mmap(0, buff->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (buff->virt_uaddr == (unsigned long)MAP_FAILED) { err_msg("Error!mmap(fd=%d, size=%u) failed (%s)", fd, buff->size, strerror(errno)); close(fd); return -1; } memset(®ion, 0, sizeof(region)); if (ioctl(fd, PMEM_GET_PHYS, ®ion) == -1) { err_msg("Error!Failed to get physical address of source!"); munmap((void *)buff->virt_uaddr, buff->size); close(fd); return -1; } buff->phy_addr = (unsigned long)region.offset; buff->cpu_addr = (unsigned long)fd; memset((void*)buff->virt_uaddr, 0, buff->size); #endif #else if (ioctl(vpu_fd, which, buff) < 0) { err_msg("mem allocation failed!\n"); buff->phy_addr = 0; buff->cpu_addr = 0; return -1; } sz_alloc += buff->size; dprintf(3, "%s: phy addr = %08lx\n", __func__, buff->phy_addr); dprintf(3, "%s: alloc=%d, total=%d\n", __func__, buff->size, sz_alloc); #endif return 0; }
JNIEXPORT jint JNICALL Java_com_example_enzocamtest_CamView_startCamera(JNIEnv* env, jobject thiz, jstring deviceName, jint width, jint height) { int ret = 0; const char* dev_name = (*env)->GetStringUTFChars(env, deviceName, 0); /* Initialize all the structures we will be using */ mjpgDec = (struct decoderInstance *)calloc(1, sizeof(struct decoderInstance)); usbCam = (struct cameraInstance *)calloc(1, sizeof(struct cameraInstance)); camData = (struct mediaBuffer *)calloc(1, sizeof(struct mediaBuffer)); yuvData = (struct mediaBuffer *)calloc(1, sizeof(struct mediaBuffer)); y422_buf = (struct g2d_buf *)calloc(1, sizeof(struct g2d_buf)); /* Set properties for H264 AVC decoder */ mjpgDec->type = MJPEG; /* Set properties for USB camera */ usbCam->type = MJPEG; usbCam->width = width; usbCam->height = height; usbCam->fps = FPS; strcpy(usbCam->deviceName, dev_name); /* Init the VPU. This must be done before a codec can be used. If this fails, we need to bail. */ ret = vpuInit(); if (ret < 0) return -1; if (cameraInit(usbCam) < 0) ret = -1; /* In order to init mjpg decoder, it must be supplied with bitstream parse */ ret = cameraGetFrame(usbCam, camData); if (ret < 0) { err_msg("Could not get camera frame\n"); ret = -1; } if (decoderInit(mjpgDec, camData) < 0) { err_msg("Could not init MJPG decoder\n"); ret = -1; } y420_buf = g2d_alloc(width * height * 2, 0); rgb_buf = g2d_alloc(width * height * 2, 0); rgb_surf.planes[0] = rgb_buf->buf_paddr; rgb_surf.left = 0; rgb_surf.top = 0; rgb_surf.right = width; rgb_surf.bottom = height; rgb_surf.stride = width; rgb_surf.width = width; rgb_surf.height = height; rgb_surf.rot = G2D_ROTATION_0; rgb_surf.format = G2D_RGB565; y420_surf.planes[0] = y420_buf->buf_paddr; y420_surf.planes[1] = y420_surf.planes[0] + width*height; y420_surf.planes[2] = y420_surf.planes[1] + width*height/4; y420_surf.left = 0; y420_surf.top = 0; y420_surf.right = width; y420_surf.bottom = height; y420_surf.stride = width; y420_surf.width = width; y420_surf.height = height; y420_surf.rot = G2D_ROTATION_0; y420_surf.format = G2D_I420; info_msg("Finished setting up JNI codec and camera!\n"); return ret; }