我是靠谱客的博主 热心星月,最近开发中收集的这篇文章主要介绍Mtk Camera 对预览和拍照做Flip + Mirror,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

(1)Sensor Drv做Flip + Mirror效果

这里列举几个示例(会影响所有输出流)

path: /kernel-4.19/drivers/misc/mediatek/imgsensor/src/mtxxxx/

//(1)gc8034mipi_Sensor.h和gc8034mipi_Sensor.c
//用于在gc8034mipi_Sensor.c来修改寄存器的值
#define  GC8034_MIRROR_NORMAL
#undef  GC8034_MIRROR_H
#undef  GC8034_MIRROR_V
#undef GC8034_MIRROR_HV

#if defined(GC8034_MIRROR_NORMAL)
	#define GC8034_MIRROR         0xc0
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x09
#elif defined(GC8034_MIRROR_H)
	#define GC8034_MIRROR         0xc1
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x0b
#elif defined(GC8034_MIRROR_V)
	#define GC8034_MIRROR         0xc2
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x09
#elif defined(GC8034_MIRROR_HV)
	#define GC8034_MIRROR         0xc3
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x0b
#else
	#define GC8034_MIRROR         0xc0
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x09
#endif

//(2)sc500csmipi_Sensor.h和sc500csmipi_Sensor.c

/* SENSOR MIRROR FLIP INFO */
#define SC500CS_MIRROR_FLIP_ENABLE         0
#if SC500CS_MIRROR_FLIP_ENABLE
#define SC500CS_MIRROR                     0x66 //mirror&flip
#else
#define SC500CS_MIRROR                     0x00 //normal
#endif

//(3)gc08a3mipi_Sensor.h和gc08a3mipi_Sensor.c

/* SENSOR MIRROR FLIP INFO */
#define GC08A3_MIRROR_NORMAL    0
#define GC08A3_MIRROR_H         0
#define GC08A3_MIRROR_V         0
#define GC08A3_MIRROR_HV        1

#if GC08A3_MIRROR_NORMAL
#define GC08A3_MIRROR	        0x00
#elif GC08A3_MIRROR_H
#define GC08A3_MIRROR	        0x01
#elif GC08A3_MIRROR_V
#define GC08A3_MIRROR	        0x02
#elif GC08A3_MIRROR_HV
#define GC08A3_MIRROR	        0x03
#else
#define GC08A3_MIRROR	        0x00
#endif

(2)API1在Framework做Flip+Mirror

//frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.cpp

previewTransform = degToTransform(0, cameraFacing == CAMERA_FACING_FRONT);

int Parameters::degToTransform(int degrees, bool mirror) {
    if (!mirror) {
        if (degrees == 0) return 0;
        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
    } else {  // Do mirror (horizontal flip)
        if (degrees == 0) {           // FLIP_H and ROT_0
            return HAL_TRANSFORM_FLIP_H;
        } else if (degrees == 90) {   // FLIP_H and ROT_90
            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
        } else if (degrees == 180) {  // FLIP_H and ROT_180
            return HAL_TRANSFORM_FLIP_V;
        } else if (degrees == 270) {  // FLIP_H and ROT_270
            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
        }
    }
    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
    return -1;
}

(3)API2在Framework做Flip+ Mirror

//frameworks/av/camera/CameraUtils.cpp

bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
    int orientation = entry.data.i32[0];
    ALOGE("%s: dxf_getRotationTransform : mirror = %d , orientation = %d", __FUNCTION__ , mirror , orientation);
    if (!mirror) {
        switch (orientation) {
            case 0:
                flags = 0;
                break;
            case 90:
                flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
                break;
            case 180:
                flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
                break;
            case 270:
                flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
                break;
            default:
                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
                      __FUNCTION__, orientation);
                return INVALID_OPERATION;
        }
    } else {
        // Front camera needs to be horizontally flipped for mirror-like behavior.
        // Note: Flips are applied before rotates; using XOR here as some of these flags are
        // composed in terms of other flip/rotation flags, and are not bitwise-ORable.
        switch (orientation) {
            case 0:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H;
                break;
            case 90:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
                        NATIVE_WINDOW_TRANSFORM_ROT_270;
                break;
            case 180:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
                        NATIVE_WINDOW_TRANSFORM_ROT_180;
                break;
            case 270:
                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
                        NATIVE_WINDOW_TRANSFORM_ROT_90;

                break;
            default:
                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
                      __FUNCTION__, orientation);
                return INVALID_OPERATION;
        }
    }

(4)JpegNode对大图做旋转和Flip操作

这里旋转有如下几种方式,可进行相互组合。

//vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/def/ImageFormat.h

enum
{
    /* do not rotate or flip image */
    eTransform_None                     = 0x00,

    /* flip source image horizontally (around the vertical axis) */  水平翻转
    eTransform_FLIP_H                   = 0x01,

    /* flip source image vertically (around the horizontal axis)*/ 垂直翻转
    eTransform_FLIP_V                   = 0x02,

    /* rotate source image 90 degrees clockwise */ 顺时针90
    eTransform_ROT_90                   = 0x04,

    /* rotate source image 180 degrees */ 倒置180
    eTransform_ROT_180                  = 0x03,

    /* rotate source image 270 degrees clockwise */ 顺时针270
    eTransform_ROT_270                  = 0x07,
};

enum EImageFormat
{
    eImgFmt_IMPLEMENTATION_DEFINED  = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,

    eImgFmt_RAW16                   = HAL_PIXEL_FORMAT_RAW16,                   /*!< raw 16-bit 1 plane */
    eImgFmt_RAW_OPAQUE              = HAL_PIXEL_FORMAT_RAW_OPAQUE,              /*!< raw 1 plane */

    /*
     * This format is used to carry task-specific data which does not have a
     * standard image structure. The details of the format are left to the two
     * endpoints.
     *
     * Buffers of this format must have a height of 1, and width equal to their
     * size in bytes.
     */
    eImgFmt_BLOB                    = HAL_PIXEL_FORMAT_BLOB,

    eImgFmt_RGBA8888                = HAL_PIXEL_FORMAT_RGBA_8888,               /*!< RGBA (32-bit; LSB:R, MSB:A), 1 plane */
    eImgFmt_RGBX8888                = HAL_PIXEL_FORMAT_RGBX_8888,               /*!< RGBX (32-bit; LSB:R, MSB:X), 1 plane */
    eImgFmt_RGB888                  = HAL_PIXEL_FORMAT_RGB_888,                 /*!< RGB 888 (24-bit), 1 plane (RGB) */
    eImgFmt_RGB565                  = HAL_PIXEL_FORMAT_RGB_565,                 /*!< RGB 565 (16-bit), 1 plane */
    eImgFmt_BGRA8888                = HAL_PIXEL_FORMAT_BGRA_8888,               /*!< BGRA (32-bit; LSB:B, MSB:A), 1 plane */

    eImgFmt_YUY2                    = HAL_PIXEL_FORMAT_YCbCr_422_I,             /*!< 422 format, 1 plane (YUYV) */

    eImgFmt_NV16                    = HAL_PIXEL_FORMAT_YCbCr_422_SP,            /*!< 422 format, 2 plane (Y),(UV) */
    eImgFmt_NV21                    = HAL_PIXEL_FORMAT_YCrCb_420_SP,            /*!< 420 format, 2 plane (Y),(VU) */
    eImgFmt_NV12                    = HAL_PIXEL_FORMAT_NV12,                    /*!< 420 format, 2 plane (Y),(UV) */

    eImgFmt_YV12                    = HAL_PIXEL_FORMAT_YV12,                    /*!< 420 format, 3 plane (Y),(V),(U) */

    eImgFmt_Y8                      = HAL_PIXEL_FORMAT_Y8,                      /*!<  8-bit Y plane */
    eImgFmt_Y800                    = eImgFmt_Y8,                               /*!< deprecated; Replace it with eImgFmt_Y8 */
    eImgFmt_Y16                     = HAL_PIXEL_FORMAT_Y16,                     /*!< 16-bit Y plane */

    eImgFmt_CAMERA_OPAQUE           = HAL_PIXEL_FORMAT_CAMERA_OPAQUE,           /*!< Opaque format, RAW10 + Metadata */

    eImgFmt_YUV_P010                = HAL_PIXEL_FORMAT_YCBCR_P010,              /*!< 420 format, 16bit, 2 plane (Y),(UV) = P010 */
    //...
}

(A)对Jpeg大图做旋转

//vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/hwnode/JpegNode/v2.0/JpegNode.cpp

JpegNodeImp::
encodeMainJpeg(
    sp<encode_frame>& pEncodeFrame)
{
    MINT8 iEncTypeCheck = isHwEncodeSupported(pEncodeFrame->mpYUV_Main->getImgFormat()) ?
                          NSSImager::JPEGENC_HW_ONLY : NSSImager::JPEGENC_SW;
    my_encode_params params;
    params.pSrc = pEncodeFrame->mpYUV_Main.get();
    params.pDst = pEncodeFrame->mpJpeg_Main.get();
    params.transform = 0; //transform——用来处理翻转问题
    params.crop = MRect(MPoint(0,0), pEncodeFrame->mpYUV_Main->getImgSize());  //crop
    params.isSOI = (!pEncodeFrame->mbSkipParseMeta) ? 0 : 1;
    params.quality = pEncodeFrame->mParams.quality;
    params.bsOffset = pEncodeFrame->exif.getHeaderSize();
    if(pEncodeFrame->miJpegEncType != -1){
        iEncTypeCheck = pEncodeFrame->miJpegEncType;
    }
    if (pEncodeFrame->muJpegSwMode > 0)
    {
        iEncTypeCheck = NSSImager::JPEGENC_SW;
    }
    params.codecType = iEncTypeCheck;
    //
    MERROR const err = hardwareOps_encode(params);
    if( err != OK ) {
        pEncodeFrame->mbSuccess = MFALSE;
    }

    pEncodeFrame->mpOutImgBufferHeap->setBitstreamSize(
        params.pDst->getBitstreamSize());
}
params.transform = 0 //不做任何处理
params.transform = eTransform_FLIP_H //水平翻转,相当于镜像
params.transform = eTransform_FLIP_V //垂直翻转,相当于上下翻转
params.transform = eTransform_ROT_90 //顺时针旋转90
params.transform = eTransform_ROT_180 //顺时针旋转180
params.transform = eTransform_FLIP_H |  eTransform_FLIP_V //水平+垂直翻转  == eTransform_ROT_180

(B)对Jpeg大图做Flip

//vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/hwnode/JpegNode/v2.0/JpegNode.cpp

MVOID
Request::
getJpegParams(
    IMetadata* pMetadata_request,
    jpeg_params& rParams
    ) const
{
    if( NULL == pMetadata_request)
    {
        MY_LOGE("pMetadata_request=NULL");
        return;
    }
    rParams.gpsCoordinates =
        pMetadata_request->entryFor(MTK_JPEG_GPS_COORDINATES);

    rParams.gpsProcessingMethod =
        pMetadata_request->entryFor(MTK_JPEG_GPS_PROCESSING_METHOD);

    rParams.gpsTimestamp =
        pMetadata_request->entryFor(MTK_JPEG_GPS_TIMESTAMP);

#define getParam(meta, tag, type, param, needWarn)      
    do {                                                
        if( !tryGetMetadata<type>(meta, tag, param) ) { 
            if (needWarn) MY_LOGW("no tag: %s", #tag);  
            else MY_LOGW_IF( mInfo.mLogLevel,"no tag: %s", #tag); 
        }                                               
    } while(0)
#define getAppParam(tag, type, param ,needWarn) getParam(pMetadata_request, tag, type, param, needWarn)

    // request from app
    getAppParam(MTK_JPEG_ORIENTATION      , MINT32, rParams.orientation, MTRUE);
    MY_LOGD("orientation:%d", rParams.orientation);
    getAppParam(MTK_JPEG_QUALITY          , MUINT8, rParams.quality, MTRUE);
    getAppParam(MTK_JPEG_THUMBNAIL_QUALITY, MUINT8, rParams.quality_thumbnail, MTRUE);
    getAppParam(MTK_JPEG_THUMBNAIL_SIZE   , MSize , rParams.size_thumbnail, MTRUE);
    getAppParam(MTK_SCALER_CROP_REGION    , MRect , rParams.cropRegion, MTRUE);

	//Flip动作
    getAppParam(MTK_CONTROL_CAPTURE_JPEG_FLIP_MODE  , MINT32, rParams.flipMode, MFALSE);

    getAppParam(MTK_VSDOF_FEATURE_REFOCUS_CAPTURE_FLOW  , MINT32, rParams.pakType, MTRUE);
#undef getAppParam
#undef getParam

}

(5)JpegNode对Thumbnail做旋转和Flip操作

//vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/hwnode/JpegNode/v2.0/JpegNode.cpp

MVOID
JpegNodeImp::
encodeThumbnailJpeg(
    sp<encode_frame>& pEncodeFrame)
{
    {
        // set thread naming
        pthread_setname_np(pthread_self(), THUMBTHREAD_NAME);
    }
    MSize thumbsize = pEncodeFrame->mParams.size_thumbnail;
    MUINT32 transform = (pEncodeFrame->mpYUV_MainStreamInfo.get()) ? pEncodeFrame->mpYUV_MainStreamInfo->getTransform() : 0;
    // do encode
    {
        my_encode_params params;
        params.frameNo = pEncodeFrame->mpFrame->getFrameNo();
        params.requestNo = pEncodeFrame->mpFrame->getRequestNo();
        params.pSrc = pEncodeFrame->mpYUV_Thumbnail.get();
        params.pDst = pEncodeFrame->mpJpeg_Thumbnail.get();
        if (pEncodeFrame->mParams.flipMode || info.mFlip) {
            if( pEncodeFrame->mParams.orientation == 90 && transform & eTransform_ROT_90)
            {
                params.transform = eTransform_ROT_90 | eTransform_FLIP_V;
                std::swap(thumbsize.w, thumbsize.h);
            } else if (pEncodeFrame->mParams.orientation == 180 && transform & eTransform_ROT_180)
            {
                params.transform = eTransform_FLIP_V;
            } else if (pEncodeFrame->mParams.orientation == 270 && transform & eTransform_ROT_270)
            {
                params.transform = eTransform_ROT_90 | eTransform_FLIP_H;
                std::swap(thumbsize.w, thumbsize.h);
            } else
            {
                params.transform = eTransform_FLIP_H;
            }

#if MTKCAM_EARLY_FLIP_SUPPORT == 1
            // has flipped in P2A, need to un-flip
            auto doUnflip= [&](MUINT32& trans, MINT32 dvOri) -> MVOID {
                if (dvOri == 270) {
                    MY_LOGD("dvOri %d, Capture vertical", dvOri);
                    trans |= eTransform_FLIP_V;
                } else if (dvOri == 90) {
                    MY_LOGD("dvOri %d, Capture vertical", dvOri);
                    trans &= ~eTransform_FLIP_V;
                } else if (dvOri == 180) {
                    MY_LOGD("dvOri %d, Capture horizontal",dvOri);
                    trans |= eTransform_FLIP_H;
                } else if (dvOri == 0) {
                    MY_LOGD("dvOri %d, Capture horizontal",dvOri);
                    trans &= ~eTransform_FLIP_H;
                }
            };
            if (pEncodeFrame->mParams.isFlipped) {
                MY_LOGD("before trans 0x%" PRIx64, params.transform);
                doUnflip(params.transform, pEncodeFrame->mParams.orientation);
                MY_LOGD("after trans 0x%" PRIx64, params.transform);
            }
#endif
        } else {
            if( pEncodeFrame->mParams.orientation == 90 && transform & eTransform_ROT_90)
            {
                params.transform = eTransform_ROT_90;
                std::swap(thumbsize.w, thumbsize.h);
            } else if (pEncodeFrame->mParams.orientation == 180 && transform & eTransform_ROT_180)
            {
                params.transform = eTransform_ROT_180;
            } else if (pEncodeFrame->mParams.orientation == 270 && transform & eTransform_ROT_270)
            {
                params.transform = eTransform_ROT_270;
                std::swap(thumbsize.w, thumbsize.h);
            } else
            {
                params.transform = 0;
            }
        }
//...
}

(5)APP下Vendor Tag来实现拍照的Mirror(或setprop)

//vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/policy/request/CaptureStreamUpdaterPolicy.cpp

static auto createRotationStreamInfoLocked_Main_YUV(
    RequestOutputParams& out __unused,
    RequestInputParams const& in __unused
) -> int
{
    auto const pMetadata    = in.pRequest_AppControl;
    auto const pCfgMainYUV  = *(in.pConfiguration_HalImage_Jpeg_YUV);
    if ( CC_UNLIKELY( ! pMetadata || ! pCfgMainYUV.get() ) ) {
        MY_LOGE("invlaid input params");
        return NO_INIT;
    }

    IMetadata::IEntry const& entryJpegOrientation = pMetadata->entryFor(MTK_JPEG_ORIENTATION);
    if  ( entryJpegOrientation.isEmpty() ) {
        MY_LOGW("No tag: MTK_JPEG_ORIENTATION");
        return -EINVAL;
    }

    int32_t jpegFlip = 0;
    //(1)通过Vendor Tag来设置Flip
    IMetadata::IEntry const& entryJpegFlip = pMetadata->entryFor(MTK_CONTROL_CAPTURE_JPEG_FLIP_MODE);
    if (entryJpegFlip.isEmpty()) {
        MY_LOGD("No tag: MTK_CONTROL_CAPTURE_JPEG_FLIP_MODE");
    } else {
        jpegFlip = entryJpegFlip.itemAt(0, Type2Type<MINT32>());
    }

	//(2)也可下系统属性来实现Flip
    int32_t jpegFlipProp = ::property_get_int32("vendor.debug.camera.Jpeg.flip", 0);

    int32_t const jpegOrientation = (in.isSupportJpegPack) ? 0 :
                                    entryJpegOrientation.itemAt(0, Type2Type<MINT32>());
    uint32_t      reqTransform   = 0;

    if (jpegFlip || jpegFlipProp) {
        if ( 0==jpegOrientation )
            reqTransform = eTransform_FLIP_H;
        else if ( 90==jpegOrientation )
            reqTransform = eTransform_ROT_90 | eTransform_FLIP_V;
        else if ( 180==jpegOrientation )
            reqTransform = eTransform_FLIP_V;
        else if ( 270==jpegOrientation )
            reqTransform = eTransform_ROT_90 | eTransform_FLIP_H;
        else
            MY_LOGW("Invalid Jpeg Orientation value: %d", jpegOrientation);
    } else {
        if ( 0==jpegOrientation )
            reqTransform = 0;
        else if ( 90==jpegOrientation )
            reqTransform = eTransform_ROT_90;
        else if ( 180==jpegOrientation )
            reqTransform = eTransform_ROT_180;
        else if ( 270==jpegOrientation )
            reqTransform = eTransform_ROT_270;
        else
            MY_LOGW("Invalid Jpeg Orientation value: %d", jpegOrientation);
    }

	uint32_t const cfgTransform   = pCfgMainYUV->getTransform();
    MY_LOGD_IF( 1, "Jpeg orientation metadata: %d degrees; transform request(%d) & config(%d) & flip(%d) pack(%d)",
                jpegOrientation, reqTransform, cfgTransform, jpegFlip, in.isSupportJpegPack);
//...
}

可在createRotationStreamInfoLocked_Main_YUV 函数中的if (jpegFlip || jpegFlipProp) 用于判断是否flip。

  • 可用Meta data MTK_CONTROL_CAPTURE_JPEG_FLIP_MODE来控制Jpeg的镜像效果;
  • 也可用adb设置属性vendor.debug.camera.Jpeg.flip 1 来debug拍照的Jpeg是否有镜像效果;

以上是拍照会走的Flow,当App设置如下Mirror的Vendor Tag后,拍照的Jpeg图片将有Flip效果。

App通过request来设置Flip

private static final String FLIP_KEY_MODE_REQUEST =
            "com.mediatek.control.capture.flipmode"

if (value != null && captureBuilder != null) {
            int[] mode = new int[1];
            mode[0] = Integer.parseInt(value);
            captureBuilder.set(mKeyMirrorRequestValue, mode);
}

(6)setprop来对录像视频和Vss照片进行Mirror(或App下Vendor Tag)

可参考如下这篇FAQ进行调试:
https://online.mediatek.com/QuickStart/QS00137#QSS01454

//vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/model/session/PipelineModelSessionBase.cpp

auto
PipelineModelSessionBase::
submitRequest(
    std::vector<std::shared_ptr<UserRequestParams>>const& requests,
    uint32_t& numRequestProcessed
) -> int
{
	//...

	 //Submit ParsedAppRequest one by one
    for (size_t i = 0; i < reqs.size(); i++, numRequestProcessed++) {


        //add mirror for video start
        int SensorID = mStaticInfo.pPipelineStaticInfo->sensorId[i];
        if(SensorID == 1){
            auto const& pAppControl = reqs[i]->pAppMetaControlStreamBuffer;
            IMetadata* pMetadata = pAppControl->tryReadLock(LOG_TAG);
            if ( CC_UNLIKELY( ! pMetadata ) ) {
                MY_LOGE("bad metadata(%p) SBuffer(%p)", pMetadata, pAppControl.get() );
                pAppControl->unlock(LOG_TAG, pMetadata);
                        return -EINVAL;
            }
            MINT32 videoFlip = 0;
            int32_t videoOrientation = 90;
            
            //(1)通过Vendor Tag / setprop
            //IMetadata::getEntry(pMetadata, MTK_CONTROL_CAPTURE_JPEG_FLIP_MODE, videoFlip);
            int32_t videoFlip = ::property_get_int32("vendor.debug.camera.videocontrol.flip", 0);
			int32_t videoOrientation = ::property_get_int32("vendor.debug.camera.videocontrol.orientation", 90);
            pAppControl->unlock(LOG_TAG, pMetadata);
            MY_LOGD("%s:videoFlip = %d videoOrientation = %dn",__FUNCTION__,videoFlip,videoOrientation);
            auto OpRequest_AppImageStreamInfo = reqs[i]->pParsedAppImageStreamInfo.get();
            for (auto & it : OpRequest_AppImageStreamInfo->vAppImage_Output_Proc) {
            	//(2)录像条件
                if (it.second->getUsageForConsumer() & GRALLOC_USAGE_HW_VIDEO_ENCODER ){
                    uint32_t reqTransform = 0;
                    if (videoFlip) {
                            if ( 0 == videoOrientation ) {
                                reqTransform = eTransform_FLIP_H;
                            }else if ( 90 == videoOrientation ) {
                                reqTransform = eTransform_FLIP_V;
                            }else if ( 180 == videoOrientation ) {
                                reqTransform = eTransform_FLIP_H;
                            }else if ( 270 == videoOrientation ) {
                                reqTransform = eTransform_FLIP_V;}
                            }else {
                                MY_LOGW("Invalid videoOrientation value: %d", videoOrientation);
                            }
                    MY_LOGD("set video flip reqTransform: %d", reqTransform);
                    it.second->setTransform(reqTransform);
                }
            }
        }
        //add mirror for video end
        
        RETURN_ERROR_IF_NOT_OK( submitOneRequest(reqs[i]),
            "submitOneRequest fail on requestNo:%u - %u/%zu requests submitted sucessfully",
            reqs[i]->requestNo, numRequestProcessed, reqs.size() );
    }

    return OK;
}

以上可对录像的视频和Vss的照片进行Flip动作。

最后

以上就是热心星月为你收集整理的Mtk Camera 对预览和拍照做Flip + Mirror的全部内容,希望文章能够帮你解决Mtk Camera 对预览和拍照做Flip + Mirror所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部