[SPRD CAMERA] 5 hal configureStreams

idh.code\vendor\sprd\interfaces\camera\device\3.2\default\CameraDeviceSession.cpp

Return<void> CameraDeviceSession::configureStreams(
        const StreamConfiguration& requestedConfiguration,
        ICameraDeviceSession::configureStreams_cb _hidl_cb)  {
    Status status = initStatus();
    HalStreamConfiguration outStreams;

    camera3_stream_configuration_t stream_list{};
    hidl_vec<camera3_stream_t*> streams;
    //使用requestedConfiguration中的信息来初始化stream_list和streams
    preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)

    status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
    
    //清除一些没有配置的流
    postProcessConfigurationLocked(requestedConfiguration);

    _hidl_cb(status, outStreams);
    return Void();
}

这里主要是使用framework层传递下来的流配置初始化stream_list。

idh.code\vendor\sprd\modules\libcamera\hal3_2v6\SprdCamera3HWI.cpp

int SprdCamera3HWI::configure_streams(
    const struct camera3_device *device,
    camera3_stream_configuration_t *stream_list) {

    SprdCamera3HWI *hw = reinterpret_cast<SprdCamera3HWI *>(device->priv);

    int ret = hw->configureStreams(stream_list);

    return ret;
}

继续跟代码

int SprdCamera3HWI::configureStreams(
    camera3_stream_configuration_t *streamList) {

    //下面三个都是创建一个和channel 相关的对象
    mMetadataChannel = new SprdCamera3MetadataChannel(
            mOEMIf, captureResultCb, mSetting, this);

    mRegularChan = new SprdCamera3RegularChannel(
            mOEMIf, captureResultCb, mSetting, mMetadataChannel,
            CAMERA_CHANNEL_TYPE_REGULAR, this);

    mPicChan = new SprdCamera3PicChannel(mOEMIf, captureResultCb, mSetting,
            mMetadataChannel,
            CAMERA_CHANNEL_TYPE_PICTURE, this);

    resetVariablesToDefault();
        //mOEMIf->initialize();
        //对oemif的变量进行初始化

    // for zero HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED stream
    for (i = 0; i < streamList->num_streams; i++) {
        if (streamList->streams[i]->stream_type == CAMERA3_STREAM_OUTPUT) {
            if (streamList->streams[i]->format ==
                    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
                streamList->streams[i]->format ==
                    HAL_PIXEL_FORMAT_YCrCb_420_SP) {
                hasImplementationDefinedOutputStream = 1;
            }
        }
    }

    mStreamConfiguration.num_streams = streamList->num_streams;

    mRegularChan->clearAllStreams();
    mPicChan->clearAllStreams();

    /* Allocate channel objects for the requested streams */
    for (i = 0; i < streamList->num_streams; i++) {
        camera3_stream_t *newStream = streamList->streams[i];
        // eis use this variable, but some chip dont support eis
        newStream->reserved[0] = NULL;
        camera_stream_type_t stream_type = CAMERA_STREAM_TYPE_DEFAULT;
        camera_channel_type_t channel_type = CAMERA_CHANNEL_TYPE_DEFAULT;

        //根据stream 的type类型 和 format格式,来初始化 stream_type(可以什么类型的流) 和 channel_type 通道类型
        if (newStream->stream_type == CAMERA3_STREAM_OUTPUT) {
            switch (newStream->format) {
            case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
                if (newStream->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
                    stream_type = CAMERA_STREAM_TYPE_VIDEO;
                    channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
                    // for vsp cant handle no 32-alignment size
                    if ((newStream->width == 1280 &&
                         newStream->height == 720) ||
                        (newStream->width == 1920 &&
                         newStream->height == 1080)) {
                        newStream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
                    } else {
                        newStream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
                    }

                } else if (alreadyHasPreviewStream == 0) {
                    stream_type = CAMERA_STREAM_TYPE_PREVIEW;
                    channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
                    newStream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
                    newStream->usage |= GRALLOC_USAGE_PRIVATE_1;
                    // for two HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED steam
                    alreadyHasPreviewStream = 1;
                } else {
                    stream_type = CAMERA_STREAM_TYPE_CALLBACK;
                    channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
                    newStream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
                    newStream->usage |= GRALLOC_USAGE_PRIVATE_1;
                }
                break;

            case HAL_PIXEL_FORMAT_YV12:
            case HAL_PIXEL_FORMAT_YCbCr_420_888:
                if (hasImplementationDefinedOutputStream == 0) {
                    stream_type = CAMERA_STREAM_TYPE_PREVIEW;
                    channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
                    // for two HAL_PIXEL_FORMAT_YCBCR_420_888 steam
                    hasImplementationDefinedOutputStream = 1;
                } else if (hasCallbackStream == 0) {
                    stream_type = CAMERA_STREAM_TYPE_CALLBACK;
                    channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
                    hasCallbackStream = 1;
                } else if (hasYuv2Stream == 0) {
                    stream_type = CAMERA_STREAM_TYPE_YUV2;
                    channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
                    hasYuv2Stream = 1;
                }
                break;

            case HAL_PIXEL_FORMAT_BLOB:
                stream_type = CAMERA_STREAM_TYPE_PICTURE_SNAPSHOT;
                channel_type = CAMERA_CHANNEL_TYPE_PICTURE;
                break;

            case HAL_PIXEL_FORMAT_RAW16:
                stream_type = CAMERA_STREAM_TYPE_PREVIEW;
                channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
                break;

            default:
                stream_type = CAMERA_STREAM_TYPE_DEFAULT;
                break;
            }
        } else if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
            stream_type = CAMERA_STREAM_TYPE_CALLBACK;
            channel_type = CAMERA_CHANNEL_TYPE_REGULAR;
            newStream->format = HAL_PIXEL_FORMAT_YCbCr_420_888;
            mInputStream = newStream;
        }

        if (!mOEMIf->IommuIsEnabled()) {
            newStream->usage |= GRALLOC_USAGE_VIDEO_BUFFER;
        }

        //根据上面的到的channel_type 和 stream_type 来初始化 mStreamConfiguration下的各种流类型变量初始化。将流添加到对应的通道中。
        switch (channel_type) {
        case CAMERA_CHANNEL_TYPE_REGULAR: {
            ret = mRegularChan->addStream(stream_type, newStream);
            if (ret) {
                HAL_LOGE("addStream failed");
            }

            if (stream_type == CAMERA_STREAM_TYPE_PREVIEW) {
                preview_size.width = newStream->width;
                preview_size.height = newStream->height;
                previewFormat = newStream->format;
                previewStreamType = CAMERA_STREAM_TYPE_PREVIEW;
                mStreamConfiguration.preview.status = CONFIGURED;
                mStreamConfiguration.preview.width = newStream->width;
                mStreamConfiguration.preview.height = newStream->height;
                mStreamConfiguration.preview.format = newStream->format;
                mStreamConfiguration.preview.type = CAMERA_STREAM_TYPE_PREVIEW;
                mStreamConfiguration.preview.stream = newStream;
            } else if (stream_type == CAMERA_STREAM_TYPE_VIDEO) {
                video_size.width = newStream->width;
                video_size.height = newStream->height;
                videoFormat = newStream->format;
                videoStreamType = CAMERA_STREAM_TYPE_VIDEO;
                mStreamConfiguration.video.status = CONFIGURED;
                mStreamConfiguration.video.width = newStream->width;
                mStreamConfiguration.video.height = newStream->height;
                mStreamConfiguration.video.format = newStream->format;
                mStreamConfiguration.video.type = CAMERA_STREAM_TYPE_VIDEO;
                mStreamConfiguration.video.stream = newStream;
            } else if (stream_type == CAMERA_STREAM_TYPE_CALLBACK) {
                property_get("persist.vendor.cam.isptool.mode.enable", value2, "false");
                property_get("persist.vendor.cam.raw.mode", value, "jpeg");
                if (strcmp(value2, "true") && strcmp(value, "raw")) {
                    callback_size.width = newStream->width;
                    callback_size.height = newStream->height;
                    callbackFormat = newStream->format;
                    callbackStreamType = CAMERA_STREAM_TYPE_CALLBACK;
                    mStreamConfiguration.yuvcallback.status = CONFIGURED;
                    mStreamConfiguration.yuvcallback.width = newStream->width;
                    mStreamConfiguration.yuvcallback.height = newStream->height;
                    mStreamConfiguration.yuvcallback.format = newStream->format;
                    mStreamConfiguration.yuvcallback.type =
                        CAMERA_STREAM_TYPE_CALLBACK;
                    mStreamConfiguration.yuvcallback.stream = newStream;}else {
                    mStreamConfiguration.num_streams = streamList->num_streams - 1;
                }
            } else if (stream_type == CAMERA_STREAM_TYPE_YUV2) {
                yuv2_size.width = newStream->width;
                yuv2_size.height = newStream->height;
                yuv2Format = newStream->format;
                yuv2StreamType = CAMERA_STREAM_TYPE_YUV2;
                mStreamConfiguration.yuv2.status = CONFIGURED;
                mStreamConfiguration.yuv2.width = newStream->width;
                mStreamConfiguration.yuv2.height = newStream->height;
                mStreamConfiguration.yuv2.format = newStream->format;
                mStreamConfiguration.yuv2.type = CAMERA_STREAM_TYPE_YUV2;
                mStreamConfiguration.yuv2.stream = newStream;
            }

            sprddefInfo = mSetting->getSPRDDEFTagPTR();
            if (preview_size.width > 3264 && preview_size.height > 2448)
                SprdCamera3RegularChannel::kMaxBuffers = 2;
            else if (sprddefInfo->slowmotion > 1) {
                SprdCamera3RegularChannel::kMaxBuffers = 24;
                if (stream_type == CAMERA_STREAM_TYPE_PREVIEW)
                    SprdCamera3RegularChannel::kMaxBuffers = 4;
            } else if (video_size.width % 4) {
                /* for sprd_eis_enable,eis video_size=normal video_size+2*/
                SprdCamera3RegularChannel::kMaxBuffers = 16;
            } else
                SprdCamera3RegularChannel::kMaxBuffers = 4;
            HAL_LOGD("slowmotion=%d, kMaxBuffers=%d", sprddefInfo->slowmotion,
                     SprdCamera3RegularChannel::kMaxBuffers);

            newStream->max_buffers = SprdCamera3RegularChannel::kMaxBuffers;
            newStream->priv = mRegularChan;
            break;
        }

        case CAMERA_CHANNEL_TYPE_PICTURE: {
            ret = mPicChan->addStream(stream_type, newStream);
            if (ret) {
                HAL_LOGE("addStream failed");
            }

            if (stream_type == CAMERA_STREAM_TYPE_PICTURE_SNAPSHOT) {
                capture_size.width = newStream->width;
                capture_size.height = newStream->height;
                captureFormat = newStream->format;
                captureStreamType = CAMERA_STREAM_TYPE_PICTURE_SNAPSHOT;
                mStreamConfiguration.snapshot.status = CONFIGURED;
                mStreamConfiguration.snapshot.width = newStream->width;
                mStreamConfiguration.snapshot.height = newStream->height;
                mStreamConfiguration.snapshot.format = newStream->format;
                mStreamConfiguration.snapshot.type =
                    CAMERA_STREAM_TYPE_PICTURE_SNAPSHOT;
                mStreamConfiguration.snapshot.stream = newStream;
            }

            newStream->priv = mPicChan;
            newStream->max_buffers = SprdCamera3PicChannel::kMaxBuffers;
            mPictureRequest = false;
            break;
        }

        default:
            HAL_LOGE("channel type is invalid channel");
            break;
        }
    }

    mOldCapIntent = SPRD_CONTROL_CAPTURE_INTENT_CONFIGURE;
    mOEMIf->SetChannelHandle(mRegularChan, mPicChan);
    mOEMIf->setUltraWideMode();

    mOEMIf->setCamStreamInfo(preview_size, previewFormat, previewStreamType);
    mOEMIf->setCamStreamInfo(capture_size, captureFormat, captureStreamType);
    mOEMIf->setCamStreamInfo(video_size, videoFormat, videoStreamType);
    mOEMIf->setCamStreamInfo(callback_size, callbackFormat, callbackStreamType);
    mOEMIf->setCamStreamInfo(yuv2_size, yuv2Format, yuv2StreamType);

    // need to update crop region each time when ConfigureStreams
    mOEMIf->setCameraConvertCropRegion();

    mSetting->setPreviewSize(preview_size);
    mSetting->setVideoSize(video_size);
    mSetting->setPictureSize(capture_size);
    mSetting->setCallbackSize(callback_size);

    mReciveQeqMax = SprdCamera3RegularChannel::kMaxBuffers;
    mFirstRequestGet = false;
    mPendingRequestsList.clear();

    return ret;
}

这个函数主要做了几件事

1、生成拍照和预览的 channel对象

2、判断流的类型 和 使用的通道

3、流注册到对应channel 中

这个部分觉得代码还是比较简单,后面需要关注怎么使用这个通道向上传递数据。

上一篇:ThingJS摄像机总结


下一篇:Luat Demo | 一文读懂,如何使用Cat.1开发板实现Camera功能