old mode 100755new mode 100644.. | .. |
---|
41 | 41 | namespace implementation { |
---|
42 | 42 | |
---|
43 | 43 | namespace { |
---|
| 44 | + |
---|
| 45 | +#define DBG_SAVE_OUTPUT 0 |
---|
| 46 | +#if DBG_SAVE_OUTPUT |
---|
| 47 | +static int dq_yuv_count = 0; |
---|
| 48 | +static int awjpec_count = 0; |
---|
| 49 | +const int output_counts = 10; |
---|
| 50 | + |
---|
| 51 | +bool saveBuffers(char *str, void *p, unsigned int length, bool is_oneframe) { |
---|
| 52 | + int fd; |
---|
| 53 | + ALOGD("Debug to save a frame!"); |
---|
| 54 | + if ((access(str, 0) != -1) && (is_oneframe)) { |
---|
| 55 | + ALOGD("File %s is exists!!!\n", str); |
---|
| 56 | + } |
---|
| 57 | + if (is_oneframe) { |
---|
| 58 | + fd = open(str, O_CREAT|O_RDWR|O_TRUNC, 0777); // save one frame data |
---|
| 59 | + } else { |
---|
| 60 | + fd = open(str, O_CREAT|O_RDWR|O_APPEND, 0777); // save more frames |
---|
| 61 | + } |
---|
| 62 | + if (!fd) { |
---|
| 63 | + ALOGE("Open file error %s", strerror(errno)); |
---|
| 64 | + return false; |
---|
| 65 | + } |
---|
| 66 | + if (write(fd, p, length)) { |
---|
| 67 | + ALOGE("Write file fail %s", strerror(errno)); |
---|
| 68 | + close(fd); |
---|
| 69 | + return true; |
---|
| 70 | + } else { |
---|
| 71 | + ALOGE("Write file fail"); |
---|
| 72 | + close(fd); |
---|
| 73 | + return false; |
---|
| 74 | + } |
---|
| 75 | +} |
---|
| 76 | + |
---|
| 77 | + |
---|
| 78 | +#endif |
---|
| 79 | + |
---|
| 80 | +void YUYVToNV21(uint8_t* image_in, |
---|
| 81 | + uint8_t* image_out, |
---|
| 82 | + int width, |
---|
| 83 | + int height) { |
---|
| 84 | + |
---|
| 85 | + int pixNUM = width * height; |
---|
| 86 | + |
---|
| 87 | + uint8_t *y = image_out; |
---|
| 88 | + uint8_t *uv = image_out + pixNUM ; |
---|
| 89 | + uint8_t *start = image_in; |
---|
| 90 | + int j = 0, k = 0; |
---|
| 91 | + |
---|
| 92 | + int index =0; |
---|
| 93 | + for (j = 0; j < pixNUM * 2; j = j + 2) { |
---|
| 94 | + *(y + index) = *(start + j); |
---|
| 95 | + index++; |
---|
| 96 | + } |
---|
| 97 | + |
---|
| 98 | + start = image_in; |
---|
| 99 | + int uv_index = 0; |
---|
| 100 | + for (j = 0; j < height; j = j + 2) { |
---|
| 101 | + for (k = j * width * 2 + 1; k < width * 2 * (j + 1); k = k + 4) { |
---|
| 102 | + *(uv + uv_index) = *(start + k + 2); |
---|
| 103 | + *(uv + uv_index + 1) = *(start + k); |
---|
| 104 | + uv_index += 2; |
---|
| 105 | + } |
---|
| 106 | + } |
---|
| 107 | +} |
---|
| 108 | + |
---|
| 109 | +int NV21Scale(uint8_t *psrc_buf_y, |
---|
| 110 | + uint8_t *psrc_buf_uv, |
---|
| 111 | + int psrc_w, |
---|
| 112 | + int psrc_h, |
---|
| 113 | + uint8_t *pdst_buf, |
---|
| 114 | + uint8_t *pdst_buf_uv, |
---|
| 115 | + int pdst_w, |
---|
| 116 | + int pdst_h, |
---|
| 117 | + libyuv::FilterModeEnum pfmode) { |
---|
| 118 | + uint8_t *i420_buf1 = (uint8_t *)malloc((psrc_w * psrc_h * 3) >> 1); |
---|
| 119 | + if (i420_buf1 == nullptr) { |
---|
| 120 | + ALOGE("malloc i420_buf1 failed!"); |
---|
| 121 | + return -1; |
---|
| 122 | + } |
---|
| 123 | + uint8_t *i420_buf2 = (uint8_t *)malloc((pdst_w * pdst_h * 3) >> 1); |
---|
| 124 | + if (i420_buf2 == nullptr) { |
---|
| 125 | + ALOGE("malloc i420_buf2 failed!"); |
---|
| 126 | + return -1; |
---|
| 127 | + } |
---|
| 128 | + |
---|
| 129 | + libyuv::NV12ToI420(psrc_buf_y, psrc_w, |
---|
| 130 | + psrc_buf_uv, psrc_w, |
---|
| 131 | + &i420_buf1[0], psrc_w, |
---|
| 132 | + &i420_buf1[psrc_w * psrc_h], psrc_w >> 1, |
---|
| 133 | + &i420_buf1[(psrc_w * psrc_h * 5) >> 2], psrc_w >> 1, |
---|
| 134 | + psrc_w, psrc_h); |
---|
| 135 | + |
---|
| 136 | + libyuv::I420Scale(&i420_buf1[0], psrc_w, |
---|
| 137 | + &i420_buf1[psrc_w * psrc_h], psrc_w >> 1, |
---|
| 138 | + &i420_buf1[(psrc_w * psrc_h * 5) >> 2], psrc_w >> 1, |
---|
| 139 | + psrc_w, psrc_h, |
---|
| 140 | + &i420_buf2[0], pdst_w, |
---|
| 141 | + &i420_buf2[pdst_w * pdst_h], pdst_w >> 1, |
---|
| 142 | + &i420_buf2[(pdst_w * pdst_h * 5) >> 2], pdst_w >> 1, |
---|
| 143 | + pdst_w, pdst_h, |
---|
| 144 | + pfmode); |
---|
| 145 | + |
---|
| 146 | + libyuv::I420ToNV12(&i420_buf2[0], pdst_w, |
---|
| 147 | + &i420_buf2[pdst_w * pdst_h], pdst_w >> 1, |
---|
| 148 | + &i420_buf2[(pdst_w * pdst_h * 5) >> 2], pdst_w >> 1, |
---|
| 149 | + pdst_buf, pdst_w, |
---|
| 150 | + pdst_buf_uv, pdst_w, |
---|
| 151 | + pdst_w,pdst_h); |
---|
| 152 | + |
---|
| 153 | + if (i420_buf1 != nullptr) { |
---|
| 154 | + free(i420_buf1); |
---|
| 155 | + } |
---|
| 156 | + if (i420_buf2 != nullptr) { |
---|
| 157 | + free(i420_buf2); |
---|
| 158 | + } |
---|
| 159 | + return 0; |
---|
| 160 | +} |
---|
| 161 | + |
---|
| 162 | + |
---|
44 | 163 | // Size of request/result metadata fast message queue. Change to 0 to always use hwbinder buffer. |
---|
45 | 164 | static constexpr size_t kMetadataMsgQueueSize = 1 << 18 /* 256kB */; |
---|
46 | 165 | |
---|
.. | .. |
---|
484 | 603 | closeOutputThread(); |
---|
485 | 604 | } |
---|
486 | 605 | |
---|
487 | | - Libve_exit2(&mDecoder); |
---|
| 606 | + if (mDecoder != NULL){ |
---|
| 607 | + Libve_exit2(&mDecoder); |
---|
| 608 | + } |
---|
488 | 609 | |
---|
489 | 610 | Mutex::Autolock _l(mLock); |
---|
490 | 611 | // free all buffers |
---|
.. | .. |
---|
731 | 852 | } |
---|
732 | 853 | configureV4l2StreamLocked(mV4l2StreamingFmt, requestFpsMax); |
---|
733 | 854 | } |
---|
| 855 | + } |
---|
| 856 | + |
---|
| 857 | + camera_metadata_entry entry = |
---|
| 858 | + mLatestReqSetting.find(ANDROID_JPEG_ORIENTATION); |
---|
| 859 | + int jpegOrientation = entry.data.u8[0]; |
---|
| 860 | + if (jpegOrientation != mCfg.jpegOrientation) { |
---|
| 861 | + mLatestReqSetting.update(ANDROID_JPEG_ORIENTATION, &mCfg.jpegOrientation, 1); |
---|
734 | 862 | } |
---|
735 | 863 | |
---|
736 | 864 | status = importRequestLocked(request, allBufPtrs, allFences); |
---|
.. | .. |
---|
1758 | 1886 | |
---|
1759 | 1887 | EXIFInfo exifInfo; |
---|
1760 | 1888 | memset(&exifInfo, 0, sizeof(EXIFInfo)); |
---|
1761 | | - //exifInfo.Orientation = jpegOrientation; |
---|
1762 | | - exifInfo.Orientation = 0; |
---|
1763 | | - exifInfo.ThumbWidth = thumbSize.width; |
---|
| 1889 | + exifInfo.Orientation = jpegOrientation; |
---|
| 1890 | + exifInfo.ThumbWidth = thumbSize.width; |
---|
1764 | 1891 | exifInfo.ThumbHeight = thumbSize.height; |
---|
1765 | 1892 | |
---|
1766 | 1893 | time_t t; |
---|
.. | .. |
---|
1823 | 1950 | exifInfo.ExposureMode = 0; |
---|
1824 | 1951 | |
---|
1825 | 1952 | int bufSize = 0; |
---|
| 1953 | +#if DBG_SAVE_OUTPUT |
---|
| 1954 | + char awjpec_path[100]; |
---|
| 1955 | + sprintf(awjpec_path, "/data/camera/jpec_%d_%dx%d.bin", |
---|
| 1956 | + awjpec_count++,mYu12Frame->mWidth,mYu12Frame->mHeight); |
---|
| 1957 | + saveBuffers(awjpec_path, (void*)mYu12FrameLayout.y, mYu12Frame->mWidth * mYu12Frame->mHeight * 3 / 2, true); |
---|
| 1958 | +#endif |
---|
1826 | 1959 | ret = AWJpecEnc(&sjpegInfo, &exifInfo, bufPtr, &bufSize); |
---|
1827 | 1960 | |
---|
1828 | 1961 | /* TODO: Not sure this belongs here, maybe better to pass jpegCodeSize out |
---|
.. | .. |
---|
1877 | 2010 | return false; |
---|
1878 | 2011 | }; |
---|
1879 | 2012 | |
---|
1880 | | - if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && req->frameIn->mFourcc != V4L2_PIX_FMT_Z16) { |
---|
| 2013 | + if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && |
---|
| 2014 | + req->frameIn->mFourcc != V4L2_PIX_FMT_Z16 && |
---|
| 2015 | + req->frameIn->mFourcc != V4L2_PIX_FMT_YUYV) { |
---|
1881 | 2016 | return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__, |
---|
1882 | 2017 | req->frameIn->mFourcc & 0xFF, |
---|
1883 | 2018 | (req->frameIn->mFourcc >> 8) & 0xFF, |
---|
.. | .. |
---|
1913 | 2048 | &parent->mDataInfo, |
---|
1914 | 2049 | &parent->mVideoConf); |
---|
1915 | 2050 | ATRACE_END(); |
---|
| 2051 | + //ALOGD("inDataSize = %d mYu12Frame wxh(%dx%d)", inDataSize, mYu12Frame->mWidth, mYu12Frame->mHeight); |
---|
1916 | 2052 | |
---|
1917 | 2053 | if (res != 0) { |
---|
1918 | 2054 | // For some webcam, the first few V4L2 frames might be malformed... |
---|
.. | .. |
---|
1926 | 2062 | return true; |
---|
1927 | 2063 | } |
---|
1928 | 2064 | } |
---|
| 2065 | + else if (req->frameIn->mFourcc == V4L2_PIX_FMT_YUYV) { |
---|
| 2066 | + ATRACE_BEGIN("YUY2toNV21"); |
---|
| 2067 | + YUYVToNV21(inData, |
---|
| 2068 | + static_cast<uint8_t*>(mYu12FrameLayout.y), |
---|
| 2069 | + mYu12Frame->mWidth, |
---|
| 2070 | + mYu12Frame->mHeight); |
---|
| 2071 | + ATRACE_END(); |
---|
| 2072 | + } |
---|
1929 | 2073 | |
---|
1930 | | - ATRACE_BEGIN("Wait for BufferRequest done"); |
---|
| 2074 | +#if DBG_SAVE_OUTPUT |
---|
| 2075 | + char yuv_path[100]; |
---|
| 2076 | + dq_yuv_count = dq_yuv_count % output_counts; |
---|
| 2077 | + sprintf(yuv_path, "/data/camera/nv21_%d_%dx%d.bin", |
---|
| 2078 | + dq_yuv_count++,mYu12Frame->mWidth,mYu12Frame->mHeight); |
---|
| 2079 | + int copySize = req->frameIn->mWidth * req->frameIn->mHeight * 3 / 2; |
---|
| 2080 | + saveBuffers(yuv_path, (void*)mYu12FrameLayout.y, copySize, true); |
---|
| 2081 | +#endif |
---|
| 2082 | + |
---|
1931 | 2083 | res = waitForBufferRequestDone(&req->buffers); |
---|
1932 | | - ATRACE_END(); |
---|
1933 | 2084 | |
---|
1934 | 2085 | if (res != 0) { |
---|
1935 | 2086 | ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res); |
---|
.. | .. |
---|
1971 | 2122 | case PixelFormat::Y16: |
---|
1972 | 2123 | case PixelFormat::YCBCR_420_888: |
---|
1973 | 2124 | case PixelFormat::YV12:{ |
---|
1974 | | - void* outLayout = sHandleImporter.lock(*(halBuf.bufPtr), halBuf.usage, inDataSize); |
---|
1975 | | - int yuv_size = mYu12Frame->mWidth * mYu12Frame->mHeight * 3/2; |
---|
1976 | | - std::memcpy(outLayout, (void*)(mYu12FrameLayout.y),yuv_size); |
---|
1977 | | - |
---|
| 2125 | + IMapper::Rect outRect {0, 0, |
---|
| 2126 | + static_cast<int32_t>(halBuf.width), |
---|
| 2127 | + static_cast<int32_t>(halBuf.height)}; |
---|
| 2128 | + YCbCrLayout outLayout = sHandleImporter.lockYCbCr(*(halBuf.bufPtr), |
---|
| 2129 | + halBuf.usage, |
---|
| 2130 | + outRect); |
---|
| 2131 | + ALOGV("%s: outLayout y %p cb %p cr %p y_str %d c_str %d c_step %d" |
---|
| 2132 | + " w = %d h = %d" |
---|
| 2133 | + " mYu12Frame w = %d h = %d", |
---|
| 2134 | + __FUNCTION__, |
---|
| 2135 | + outLayout.y, |
---|
| 2136 | + outLayout.cb, |
---|
| 2137 | + outLayout.cr, |
---|
| 2138 | + outLayout.yStride, |
---|
| 2139 | + outLayout.cStride, |
---|
| 2140 | + outLayout.chromaStep, |
---|
| 2141 | + halBuf.width, |
---|
| 2142 | + halBuf.height, |
---|
| 2143 | + mYu12Frame->mWidth, |
---|
| 2144 | + mYu12Frame->mHeight); |
---|
| 2145 | + if (mYu12Frame->mWidth != halBuf.width || mYu12Frame->mHeight != halBuf.height) { |
---|
| 2146 | + int ret = NV21Scale(static_cast<uint8_t*>(mYu12FrameLayout.y), |
---|
| 2147 | + static_cast<uint8_t*>(mYu12FrameLayout.cb), |
---|
| 2148 | + mYu12Frame->mWidth, |
---|
| 2149 | + mYu12Frame->mHeight, |
---|
| 2150 | + static_cast<uint8_t*>(outLayout.y), |
---|
| 2151 | + static_cast<uint8_t*>(outLayout.cr), |
---|
| 2152 | + halBuf.width, |
---|
| 2153 | + halBuf.height, |
---|
| 2154 | + libyuv::FilterMode::kFilterNone); |
---|
| 2155 | + if (ret != 0) { |
---|
| 2156 | + ALOGE("%s: NV12Scale failed!!", __FUNCTION__); |
---|
| 2157 | + } |
---|
| 2158 | + } else { |
---|
| 2159 | + int y_size = mYu12Frame->mWidth * mYu12Frame->mHeight; |
---|
| 2160 | + int c_size = mYu12Frame->mWidth * mYu12Frame->mHeight / 2; |
---|
| 2161 | + std::memcpy(outLayout.y, mYu12FrameLayout.y, y_size); |
---|
| 2162 | + std::memcpy(outLayout.cr, mYu12FrameLayout.cb, c_size - 1); |
---|
| 2163 | + } |
---|
1978 | 2164 | int relFence = sHandleImporter.unlock(*(halBuf.bufPtr)); |
---|
1979 | 2165 | if (relFence >= 0) { |
---|
1980 | 2166 | halBuf.acquireFence = relFence; |
---|
.. | .. |
---|
2694 | 2880 | } |
---|
2695 | 2881 | // Find the smallest format that matches the desired aspect ratio and is wide/high enough |
---|
2696 | 2882 | SupportedV4L2Format v4l2Fmt {.width = 0, .height = 0}; |
---|
| 2883 | + |
---|
| 2884 | + bool hasMjpeg = false; |
---|
2697 | 2885 | for (const auto& fmt : mSupportedFormats) { |
---|
| 2886 | + if (fmt.fourcc == V4L2_PIX_FMT_MJPEG) { |
---|
| 2887 | + hasMjpeg = true; |
---|
| 2888 | + break; |
---|
| 2889 | + } |
---|
| 2890 | + } |
---|
| 2891 | + for (const auto& fmt : mSupportedFormats) { |
---|
| 2892 | + if (hasMjpeg && fmt.fourcc != V4L2_PIX_FMT_MJPEG) { |
---|
| 2893 | + continue; |
---|
| 2894 | + } |
---|
2698 | 2895 | uint32_t dim = (mCroppingType == VERTICAL) ? fmt.width : fmt.height; |
---|
2699 | 2896 | if (dim >= maxDim) { |
---|
2700 | 2897 | float aspectRatio = ASPECT_RATIO(fmt); |
---|
.. | .. |
---|
2709 | 2906 | if (v4l2Fmt.width == 0) { |
---|
2710 | 2907 | // Cannot find exact good aspect ratio candidate, try to find a close one |
---|
2711 | 2908 | for (const auto& fmt : mSupportedFormats) { |
---|
| 2909 | + if (hasMjpeg && fmt.fourcc != V4L2_PIX_FMT_MJPEG) { |
---|
| 2910 | + continue; |
---|
| 2911 | + } |
---|
2712 | 2912 | uint32_t dim = (mCroppingType == VERTICAL) ? fmt.width : fmt.height; |
---|
2713 | 2913 | if (dim >= maxDim) { |
---|
2714 | 2914 | float aspectRatio = ASPECT_RATIO(fmt); |
---|
.. | .. |
---|
2738 | 2938 | return Status::INTERNAL_ERROR; |
---|
2739 | 2939 | } |
---|
2740 | 2940 | |
---|
| 2941 | + if (v4l2Fmt.fourcc == V4L2_PIX_FMT_MJPEG) { |
---|
| 2942 | + memset(&mVideoConf, 0, sizeof(mVideoConf)); |
---|
| 2943 | + mVideoConf.memops = NULL; |
---|
| 2944 | + mVideoConf.eOutputPixelFormat = PIXEL_FORMAT_NV21; |
---|
| 2945 | + mVideoConf.bDisable3D = 1; |
---|
| 2946 | + mVideoConf.bScaleDownEn = 0; |
---|
| 2947 | + mVideoConf.bRotationEn = 0; |
---|
| 2948 | + mVideoConf.bSecOutputEn = 0; |
---|
| 2949 | + mVideoConf.bDispErrorFrame = 1; |
---|
| 2950 | + mVideoConf.nVbvBufferSize = 0; |
---|
| 2951 | + mVideoConf.nAlignStride = 32; |
---|
2741 | 2952 | |
---|
2742 | | - memset(&mVideoConf, 0, sizeof(mVideoConf)); |
---|
2743 | | - mVideoConf.memops = NULL; |
---|
2744 | | - mVideoConf.eOutputPixelFormat = PIXEL_FORMAT_NV21; |
---|
2745 | | - mVideoConf.bDisable3D = 1; |
---|
2746 | | - mVideoConf.bScaleDownEn = 0; |
---|
2747 | | - mVideoConf.bRotationEn = 0; |
---|
2748 | | - mVideoConf.bSecOutputEn = 0; |
---|
2749 | | - mVideoConf.bDispErrorFrame = 1; |
---|
2750 | | - mVideoConf.nVbvBufferSize = 0; |
---|
2751 | | - mVideoConf.nAlignStride = 32; |
---|
2752 | | - |
---|
2753 | | - mVideoInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MJPEG; |
---|
2754 | | - mVideoInfo.nWidth = v4l2Fmt.width; |
---|
2755 | | - mVideoInfo.nHeight = v4l2Fmt.height; |
---|
2756 | | - ALOGD("FUNC:%s, Line:%d width = %d,height = %d,", __FUNCTION__, __LINE__, |
---|
2757 | | - mVideoInfo.nWidth,mVideoInfo.nHeight); |
---|
2758 | | - mVideoInfo.nFrameRate = mFrameRate; |
---|
2759 | | - mVideoInfo.nFrameDuration = 1000 * 1000 / mFrameRate; |
---|
2760 | | - mVideoInfo.nAspectRatio = 1000; |
---|
2761 | | - mVideoInfo.bIs3DStream = 0; |
---|
2762 | | - mVideoInfo.nCodecSpecificDataLen = 0; |
---|
2763 | | - mVideoInfo.pCodecSpecificData = NULL; |
---|
2764 | | - if(mDecoder != NULL){ |
---|
2765 | | - Libve_exit2(&mDecoder); |
---|
2766 | | - } |
---|
2767 | | - Libve_init2(&mDecoder, &mVideoInfo, &mVideoConf); |
---|
2768 | | - if(mDecoder == NULL){ |
---|
2769 | | - ALOGE("FUNC:%s, Line:%d ",__FUNCTION__,__LINE__); |
---|
| 2953 | + mVideoInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MJPEG; |
---|
| 2954 | + mVideoInfo.nWidth = v4l2Fmt.width; |
---|
| 2955 | + mVideoInfo.nHeight = v4l2Fmt.height; |
---|
| 2956 | + ALOGD("FUNC:%s, Line:%d width = %d,height = %d,", |
---|
| 2957 | + __FUNCTION__, |
---|
| 2958 | + __LINE__, |
---|
| 2959 | + mVideoInfo.nWidth, |
---|
| 2960 | + mVideoInfo.nHeight); |
---|
| 2961 | + mVideoInfo.nFrameRate = mFrameRate; |
---|
| 2962 | + mVideoInfo.nFrameDuration = 1000 * 1000 / mFrameRate; |
---|
| 2963 | + mVideoInfo.nAspectRatio = 1000; |
---|
| 2964 | + mVideoInfo.bIs3DStream = 0; |
---|
| 2965 | + mVideoInfo.nCodecSpecificDataLen = 0; |
---|
| 2966 | + mVideoInfo.pCodecSpecificData = NULL; |
---|
| 2967 | + if (mDecoder != NULL) { |
---|
| 2968 | + Libve_exit2(&mDecoder); |
---|
| 2969 | + } |
---|
| 2970 | + Libve_init2(&mDecoder, &mVideoInfo, &mVideoConf); |
---|
| 2971 | + if (mDecoder == NULL) { |
---|
| 2972 | + ALOGE("FUNC:%s, Line:%d ", __FUNCTION__, __LINE__); |
---|
| 2973 | + } |
---|
2770 | 2974 | } |
---|
2771 | 2975 | |
---|
2772 | 2976 | Size v4lSize = {v4l2Fmt.width, v4l2Fmt.height}; |
---|