int PreviewStream::freeBuffers() { status_t ret = NO_ERROR; GraphicBufferMapper& mapper = GraphicBufferMapper::get(); // Give the buffers back to display here - sort of free it if (mNativeWindow) { for (int i = 0; i < mTotalBuffers; i++) { mapper.unlock(mCameraBuffer[i].mBufHandle); ret = mNativeWindow->cancel_buffer(mNativeWindow, &mCameraBuffer[i].mBufHandle); if (ENODEV == ret) { FLOGE("Preview surface abandoned!"); mNativeWindow = NULL; return -ret; } else if (NO_ERROR != ret) { FLOGE("cancel_buffer() failed: %s (%d)", strerror(-ret), -ret); return -ret; } } } else { FLOGE("mNativeWindow is NULL"); } // /Clear the frames with camera adapter map dispatchBuffers(NULL, 0, BUFFER_DESTROY); return ret; }
int PhysMemAdapter::freeBuffer() { if (mIonFd <= 0) { FLOGE("try to free buffer from ion in preview or ion invalid"); return BAD_VALUE; } FLOGI("freeBufferToIon buffer num:%d", mBufferCount); for (int i = 0; i < mBufferCount; i++) { struct ion_handle *ionHandle = (struct ion_handle *)mCameraBuffer[i].mBufHandle; ion_free(mIonFd, ionHandle); munmap(mCameraBuffer[i].mVirtAddr, mCameraBuffer[i].mSize); } memset(mCameraBuffer, 0, sizeof(mCameraBuffer)); dispatchBuffers(NULL, 0, BUFFER_DESTROY); return NO_ERROR; }
int PhysMemAdapter::allocatePictureBuffer(int width, int height, int format, int numBufs) { if (mIonFd <= 0) { FLOGE("try to allocate buffer from ion in preview or ion invalid"); return BAD_VALUE; } int size = 0; if ((width == 0) || (height == 0)) { FLOGE("allocateBufferFromIon: width or height = 0"); return BAD_VALUE; } switch (format) { case HAL_PIXEL_FORMAT_YCbCr_420_SP: size = width * ((height + 16) & (~15)) * 3 / 2; break; case HAL_PIXEL_FORMAT_YCbCr_420_P: size = width * height * 3 / 2; break; case HAL_PIXEL_FORMAT_YCbCr_422_I: size = width * height * 2; break; default: FLOGE("Error: format not supported int ion alloc"); return BAD_VALUE; } unsigned char *ptr = NULL; int sharedFd; int phyAddr; struct ion_handle *ionHandle; size = (size + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1)); FLOGI("allocateBufferFromIon buffer num:%d", numBufs); for (int i = 0; i < numBufs; i++) { ionHandle = NULL; int err = ion_alloc(mIonFd, size, 8, 1, &ionHandle); if (err) { FLOGE("ion_alloc failed."); return BAD_VALUE; } err = ion_map(mIonFd, ionHandle, size, PROT_READ | PROT_WRITE, MAP_SHARED, 0, &ptr, &sharedFd); if (err) { FLOGE("ion_map failed."); return BAD_VALUE; } phyAddr = ion_phys(mIonFd, ionHandle); if (phyAddr == 0) { FLOGE("ion_phys failed."); return BAD_VALUE; } FLOG_RUNTIME("phyalloc ptr:0x%x, phy:0x%x, size:%d", (int)ptr, phyAddr, size); mCameraBuffer[i].reset(); mCameraBuffer[i].mIndex = i; mCameraBuffer[i].mWidth = width; mCameraBuffer[i].mHeight = height; mCameraBuffer[i].mFormat = format; mCameraBuffer[i].mVirtAddr = ptr; mCameraBuffer[i].mPhyAddr = phyAddr; mCameraBuffer[i].mSize = size; mCameraBuffer[i].mBufHandle = (buffer_handle_t *)ionHandle; close(sharedFd); } mBufferCount = numBufs; mQueueableCount = numBufs; mFormat = format; mBufferSize = mCameraBuffer[0].mSize; mFrameWidth = width; mFrameHeight = height; dispatchBuffers(&mCameraBuffer[0], numBufs, BUFFER_CREATE); return NO_ERROR; }
int PreviewStream::allocateBuffers(int /*width*/, int /*height*/, int /*format*/, int /*numBufs*/ ) { int index = -1; int ret = NO_ERROR; //In DeviceAdapter::handleFrameRelease, if mPreviewing is false, //will not dec mRefCount. This will happen when performance is low. //So need zero ref count. for (int i = 0; i < mTotalBuffers; i++) { // FLOGI("==== PreviewStream::allocateBuffers, i %d, state %d, ref %d", // i, mCameraBuffer[i].getState(), mCameraBuffer[i].getRefCount()); mCameraBuffer[i].ZeroRefCount(); } for (int i = 0; i < mMaxProducerBuffers; i++) { buffer_handle_t *buf_h = NULL; ret = mNativeWindow->dequeue_buffer(mNativeWindow, &buf_h); if (ret != 0) { FLOGE("dequeueBuffer failed: %s (%d)", strerror(-ret), -ret); if (ENODEV == ret) { FLOGE("Preview surface abandoned!"); mNativeWindow = NULL; } return ret; } index = getBufferIdx(buf_h); if (index < 0 || index >= mTotalBuffers) { FLOGE("%s dequeue invalid buffer", __FUNCTION__); return BAD_VALUE; } mCameraBuffer[index].setState(CameraFrame::BUFS_FREE); if(mDeviceAdapter.get() && mDeviceAdapter->UseMJPG()) { mDeviceAdapter.get()->mVPUPhyAddr[i] = (unsigned char*)mCameraBuffer[index].mPhyAddr; mDeviceAdapter.get()->mVPUVirtAddr[i] = (unsigned char*)mCameraBuffer[index].mVirtAddr; FLOGI("allocateBuffers, index %d, phyAddr 0x%x", index, mCameraBuffer[index].mPhyAddr); } } for (int i = 0; i < mTotalBuffers; i++) { int state = mCameraBuffer[i].getState(); if (state != CameraFrame::BUFS_FREE) { mCameraBuffer[i].setState(CameraFrame::BUFS_IN_SERVICE); // The frame held in service. // Make sure we dont add one more reference // count for it if(!mCameraBuffer[i].getRefCount()) mCameraBuffer[i].addReference(); } if(mDeviceAdapter.get() && mDeviceAdapter->UseMJPG()) { mCameraBuffer[i].mBindUVCBufIdx = -1; mCameraBuffer[i].mpFrameBuf = NULL; } } dispatchBuffers(&mCameraBuffer[0], mTotalBuffers, BUFFER_CREATE); return ret; }