联系qq [email protected]
由上一篇文件介绍hal 架构在v4l2上面进行了封装那么hal中如何去拿到拍照数据流尼
QCameraPostProc.cpp doReprocess()//拍照
QCamera2HWICallbacks.cpp synchronous_stream_cb_routine//预览
QCamera2HWICallbacks.cpp video_stream_cb_routine//录像
下面讲述一下简单的获取yuv拍照数据流算法处理过程在原来的doReprocess()函数增加下面加粗的代码
在这里添加我们自己的算法
memcpy(dataz,(unsigned char *)pReprocFrame->buffer,768*512*3/2);
/////这里添加我们的算法对dataz buf处理/////////////////
memcpy((unsigned char *)pReprocFrame->buffer,dataz,768*512*3/2);//拷贝回去
if (mPPChannels[mCurChannelIdx] != NULL) {
ppreq_job->reprocCount = (int8_t) (mCurReprocCount + 1);
if ((m_parent->isRegularCapture()) || (ppreq_job->offline_buffer)) {
m_bufCountPPQ++;
if (m_ongoingPPQ.enqueue((void *)ppreq_job)) {
pthread_mutex_lock(&m_reprocess_lock);
ret = mPPChannels[mCurChannelIdx]->doReprocessOffline(ppInputFrame,
meta_buf, m_parent->mParameters);
if (ret != NO_ERROR) {
pthread_mutex_unlock(&m_reprocess_lock);
goto end;
}
if ((ppreq_job->offline_buffer) &&
(ppreq_job->offline_reproc_buf)) {
mPPChannels[mCurChannelIdx]->doReprocessOffline(
ppreq_job->offline_reproc_buf, meta_buf);
}
pthread_mutex_unlock(&m_reprocess_lock);
} else {
LOGW("m_ongoingPPQ is not active!!!");
ret = UNKNOWN_ERROR;
goto end;
}
} else {
////////////////////////修改代码层////////////////////////////////
pthread_mutex_lock(&m_post_algo_lock);
mm_camera_buf_def_t *pReprocFrame = NULL;
QCameraStream * pSnapshotStream = NULL;
QCameraChannel *pChannel = m_parent->getChannelByHandle(ppInputFrame->ch_id);
if (pChannel == NULL)
{
for (int8_t i = 0; i < mPPChannelCount; i++)
{
if ((mPPChannels[i] != NULL) &&(mPPChannels[i]->getMyHandle() == ppInputFrame->ch_id))
{
pChannel = mPPChannels[i];
break;
}
}
}
if (pChannel == NULL)
{
LOGE("No corresponding channel (ch_id = %d) exist, return here",ppInputFrame->ch_id);
pthread_mutex_unlock(&m_post_algo_lock);
return BAD_VALUE;
}
for (uint32_t i = 0; i < ppInputFrame->num_bufs; i++)
{
pSnapshotStream = pChannel->getStreamByHandle(ppInputFrame->bufs[i]->stream_id);
if (pSnapshotStream != NULL)
{
if (pSnapshotStream->getMyType() == CAM_STREAM_TYPE_SNAPSHOT)
{
pReprocFrame = ppInputFrame->bufs[i];
break;
}
}
}
if (pReprocFrame != NULL)
{
uint32_t m_framelength=0;
cam_frame_len_offset_t offset;
pSnapshotStream->getFrameOffset(offset);
m_framelength = offset.mp[0].stride * offset.mp[0].scanline * 3 / 2;
LOGE("jianghaifeng%d,%d,%d,%d",offset.mp[0].stride, offset.mp[0].scanline,offset.mp[0].width,offset.mp[0].height);
unsigned char *dataz=(unsigned char*)malloc(768*1000*3/2);
memcpy(dataz,(unsigned char *)pReprocFrame->buffer,768*512*3/2);
/////这里添加我们的算法/////////////////
memcpy((unsigned char *)pReprocFrame->buffer,dataz,768*512*3/2);
}
else
{
if (ppreq_job != NULL)
{
releaseOngoingPPData(ppreq_job, this);
free(ppreq_job);
ppreq_job = NULL;
}
pthread_mutex_unlock(&m_post_algo_lock);
return NO_ERROR;
}
pthread_mutex_unlock(&m_post_algo_lock);
////////////////////////////结束//////////////////////////////////////////////
m_bufCountPPQ++;
if (!m_ongoingPPQ.enqueue((void *)ppreq_job)) {
LOGW("m_ongoingJpegQ is not active!!!");
ret = UNKNOWN_ERROR;
goto end;
}
int32_t numRequiredPPQBufsForSingleOutput = (int32_t)
m_parent->mParameters.getNumberInBufsForSingleShot();
if (m_bufCountPPQ % numRequiredPPQBufsForSingleOutput == 0) {
int32_t extra_pp_job_count =
m_parent->mParameters.getNumberOutBufsForSingleShot() -
m_parent->mParameters.getNumberInBufsForSingleShot();
for (int32_t i = 0; i < extra_pp_job_count; i++) {
qcamera_pp_data_t *extra_pp_job =
(qcamera_pp_data_t *)calloc(1, sizeof(qcamera_pp_data_t));
if (!extra_pp_job) {
LOGE("no mem for qcamera_pp_data_t");
ret = NO_MEMORY;
break;
}
extra_pp_job->reprocCount = ppreq_job->reprocCount;
if (!m_ongoingPPQ.enqueue((void *)extra_pp_job)) {
LOGW("m_ongoingJpegQ is not active!!!");
releaseOngoingPPData(extra_pp_job, this);
free(extra_pp_job);
extra_pp_job = NULL;
goto end;
}
}
}
ret = mPPChannels[mCurChannelIdx]->doReprocess(ppInputFrame,
m_parent->mParameters, pMetaStream, meta_buf_index);
}
} else {
LOGE("Reprocess channel is NULL");
ret = UNKNOWN_ERROR;
}
end:
if (ret != NO_ERROR) {
releaseOngoingPPData(ppreq_job, this);
if (ppreq_job != NULL) {
free(ppreq_job);
ppreq_job = NULL;
}
}
return ret;
2,预览数据流
video_stream_cb_routine//录像
LOGD("[KPI Perf] : BEGIN");
QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
if (pme == NULL ||
pme->mCameraHandle == NULL ||
pme->mCameraHandle->camera_handle != super_frame->camera_handle){
LOGE("camera obj not valid");
// simply free super frame
free(super_frame);
return;
}
mm_camera_buf_def_t *frame = super_frame->bufs[0];
//////////////////////////////////////////////////////////////////////
pthread_mutex_t m_algo_lock1;
pthread_mutex_lock(&m_algo_lock1);
cam_frame_len_offset_t offset;
stream->getFrameOffset(offset);
//LOGE("jianghaifeng%d,%d,%d,%d",offset.mp[0].stride, offset.mp[0].scanline,offset.mp[0].width,offset.mp[0].height);
memcpy(vdataz,(unsigned char *)frame->buffer,offset.mp[0].stride*offset.mp[0].scanline*3/2);
//////////////添加自己的算法处理对vdataz buf///////////////////////////////
memcpy((unsigned char *)frame->buffer,vdataz,offset.mp[0].stride*offset.mp[0].scanline*3/2);
pthread_mutex_unlock(&m_algo_lock1);
////////////////////////////////////////////////
if (pme->needDebugFps()) {
pme->debugShowVideoFPS();
}
if(pme->m_bRecordStarted) {
LOGI("[KPI Perf] : PROFILE_FIRST_RECORD_FRAME");
pme->m_bRecordStarted = false ;
}
3录像和预览差不多这里就省略了。。。。。。。。