size_t C2DColorConverter::calcSizeAlign(ColorConvertFormat format) { if (!isYUVSurface(format)) return 1; //no requirement switch (format) { case YCbCr420SP: //OR NV12 case YCbCr420P: case NV12_2K: return ALIGN4K; default: ALOGE("unknown format passed for size alignment number"); return 1; } }
void* C2DColorConverter::getDummySurfaceDef(ColorConvertFormat format, size_t width, size_t height, bool isSource) { if (isYUVSurface(format)) { C2D_YUV_SURFACE_DEF * surfaceDef = new C2D_YUV_SURFACE_DEF; surfaceDef->format = getC2DFormat(format); surfaceDef->width = width; surfaceDef->height = height; surfaceDef->plane0 = (void *)0xaaaaaaaa; surfaceDef->phys0 = (void *)0xaaaaaaaa; surfaceDef->stride0 = calcStride(format, width); surfaceDef->plane1 = (void *)0xaaaaaaaa; surfaceDef->phys1 = (void *)0xaaaaaaaa; surfaceDef->stride1 = calcStride(format, width); surfaceDef->stride2 = 0; if (format == YCbCr420P || format == YCrCb420P) { printf("half stride for Cb Cr planes \n"); surfaceDef->stride1 = calcStride(format, width) / 2; surfaceDef->phys2 = (void *)0xaaaaaaaa; surfaceDef->stride2 = calcStride(format, width) / 2; } mC2DCreateSurface(isSource ? &mSrcSurface : &mDstSurface, isSource ? C2D_SOURCE : C2D_TARGET, (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY), &(*surfaceDef)); return ((void *)surfaceDef); } else { C2D_RGB_SURFACE_DEF * surfaceDef = new C2D_RGB_SURFACE_DEF; surfaceDef->format = getC2DFormat(format); surfaceDef->width = width; surfaceDef->height = height; surfaceDef->buffer = (void *)0xaaaaaaaa; surfaceDef->phys = (void *)0xaaaaaaaa; surfaceDef->stride = calcStride(format, width); mC2DCreateSurface(isSource ? &mSrcSurface : &mDstSurface, isSource ? C2D_SOURCE : C2D_TARGET, (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY), &(*surfaceDef)); return ((void *)surfaceDef); } }
int32_t C2DColorConverter::dumpOutput(char * filename, char mode) { int fd; size_t stride, sliceHeight; if (!filename) return -1; int flags = O_RDWR | O_CREAT; if (mode == 'a') { flags |= O_APPEND; } if ((fd = open(filename, flags)) < 0) { ALOGE("open dump file failed w/ errno %s", strerror(errno)); return -1; } int ret = 0; if (isYUVSurface(mDstFormat)) { C2D_YUV_SURFACE_DEF * dstSurfaceDef = (C2D_YUV_SURFACE_DEF *)mDstSurfaceDef; uint8_t * base = (uint8_t *)dstSurfaceDef->plane0; stride = dstSurfaceDef->stride0; sliceHeight = dstSurfaceDef->height; /* dump luma */ for (size_t i = 0; i < sliceHeight; i++) { ret = write(fd, base, mDstWidth); //will work only for the 420 ones if (ret < 0) goto cleanup; base += stride; } if (mDstFormat == YCbCr420P || mDstFormat == YCrCb420P) { printf("Dump Cb and Cr separately for Planar\n"); //dump Cb/Cr base = (uint8_t *)dstSurfaceDef->plane1; stride = dstSurfaceDef->stride1; for (size_t i = 0; i < sliceHeight/2;i++) { //will work only for the 420 ones ret = write(fd, base, mDstWidth/2); if (ret < 0) goto cleanup; base += stride; } //dump Cr/Cb base = (uint8_t *)dstSurfaceDef->plane2; stride = dstSurfaceDef->stride2; for (size_t i = 0; i < sliceHeight/2;i++) { //will work only for the 420 ones ret = write(fd, base, mDstWidth/2); if (ret < 0) goto cleanup; base += stride; } } else { /* dump chroma */ base = (uint8_t *)dstSurfaceDef->plane1; stride = dstSurfaceDef->stride1; for (size_t i = 0; i < sliceHeight/2;i++) { //will work only for the 420 ones ret = write(fd, base, mDstWidth); if (ret < 0) goto cleanup; base += stride; } } } else { C2D_RGB_SURFACE_DEF * dstSurfaceDef = (C2D_RGB_SURFACE_DEF *)mDstSurfaceDef; uint8_t * base = (uint8_t *)dstSurfaceDef->buffer; stride = dstSurfaceDef->stride; sliceHeight = dstSurfaceDef->height; printf("rgb surface base is %p", base); printf("rgb surface dumpsslice height is %d\n", sliceHeight); printf("rgb surface dump stride is %d\n", stride); int bpp = 1; //bytes per pixel if (mDstFormat == RGB565) { bpp = 2; } else if (mDstFormat == RGBA8888) { bpp = 4; } int count = 0; for (size_t i = 0; i < sliceHeight; i++) { ret = write(fd, base, mDstWidth*bpp); if (ret < 0) { printf("write failed, count = %d\n", count); goto cleanup; } base += stride; count += stride; } } cleanup: if (ret < 0) { ALOGE("file write failed w/ errno %s", strerror(errno)); } close(fd); return ret < 0 ? ret : 0; }
int C2DColorConverter::convertC2D(int srcFd, void * srcData, int dstFd, void * dstData) { C2D_STATUS ret; if (mError) { ALOGE("C2D library initialization failed\n"); return mError; } if ((srcFd < 0) || (dstFd < 0) || (srcData == NULL) || (dstData == NULL)) { ALOGE("Incorrect input parameters\n"); return -1; } if (isYUVSurface(mSrcFormat)) { ret = updateYUVSurfaceDef(srcFd, srcData, true); } else { ret = updateRGBSurfaceDef(srcFd, srcData, true); } if (ret != C2D_STATUS_OK) { ALOGE("Update src surface def failed\n"); return -ret; } if (isYUVSurface(mDstFormat)) { ret = updateYUVSurfaceDef(dstFd, dstData, false); } else { ret = updateRGBSurfaceDef(dstFd, dstData, false); } if (ret != C2D_STATUS_OK) { ALOGE("Update dst surface def failed\n"); return -ret; } mBlit.surface_id = mSrcSurface; ret = mC2DDraw(mDstSurface, C2D_TARGET_ROTATE_0, 0, 0, 0, &mBlit, 1); mC2DFinish(mDstSurface); bool unmappedSrcSuccess; if (isYUVSurface(mSrcFormat)) { unmappedSrcSuccess = unmapGPUAddr((uint32_t)((C2D_YUV_SURFACE_DEF *)mSrcSurfaceDef)->phys0); } else { unmappedSrcSuccess = unmapGPUAddr((uint32_t)((C2D_RGB_SURFACE_DEF *)mSrcSurfaceDef)->phys); } bool unmappedDstSuccess; if (isYUVSurface(mDstFormat)) { unmappedDstSuccess = unmapGPUAddr((uint32_t)((C2D_YUV_SURFACE_DEF *)mDstSurfaceDef)->phys0); } else { unmappedDstSuccess = unmapGPUAddr((uint32_t)((C2D_RGB_SURFACE_DEF *)mDstSurfaceDef)->phys); } if (ret != C2D_STATUS_OK) { ALOGE("C2D Draw failed\n"); return -ret; //c2d err values are positive } else { if (!unmappedSrcSuccess || !unmappedDstSuccess) { ALOGE("unmapping GPU address failed\n"); return -1; } return ret; } }