主要文件:
vendor\mediatek\proprietary\hardware\mtkcam3\pipeline\hwnode\JpegNode.cpp
JpegNode.cpp 部分方法:
分析 JpegNode 中拍照流程
JpegNode.cpp 中實現了JpegNodeImp 類的聲明和定義。
創建兩個線程:
- 生成圖片的線程
bool
JpegNodeImp::EncodeThread::
threadLoop()
{
sp<IPipelineFrame> pFrame;
if (
!exitPending()
&& OK == mpNodeImp->onDequeRequest(pFrame)
&& pFrame != 0
)
{
mpNodeImp->mThumbDoneFlag = MTRUE;
mpNodeImp->onProcessFrame(pFrame);
return true;
}
MY_LOGD("exit encode thread %d", mpNodeImp->mThumbDoneFlag);
return false;
}
- 生成微縮圖的線程
bool
JpegNodeImp::EncodeThumbThread::
threadLoop()
{
mpNodeImp->encodeThumbnail(mpNodeImp->mpEncodeFrame);
{
Mutex::Autolock _l(mpNodeImp->mEncodeLock);
mpNodeImp->mThumbDoneFlag = MTRUE;
mpNodeImp->mEncodeCond.signal();
}
MY_LOGD_IF(mpNodeImp->mLogLevel, "exit thumb encode thread");
return false;
}
onProcessFrame 分析:
閱讀源碼可知核心函數 onProcessFrame
我們重點關注 onProcessFrame 生成照片的函數
MVOID JpegNodeImp::onProcessFrame(android::sp<IPipelineFrame> const& pFrame);
onProcessFrame 函數中代碼太長,用文字簡要描述下具體功能:
傳入的參數 android::sp<IPipelineFrame> const& pFrame
1. 獲取輸入 mpInHalMeta
2. 獲取微縮圖 thumbnail
3. new encode_frame(pFrame, useThumbnail); 創建幀編碼
4. 獲取編碼 JPEG 參數
5. 獲取 HAL meta
6. 從 HAL meta 中獲取 miJpegEncType
7. 在 exif 保存圖像是否旋轉
8. 使用 updateStdExifParam 函數獲取標準的 JPEG exif
9. 獲取 encode_frame 輸出的 ImgStreamBuffer
10. 使用指針保存 mainImgBuffer 和 thumbImgBuffer
11. 調用 hardwareOps_encode 方法編碼 JPEG
MERROR
JpegNodeImp::hardwareOps_encode( my_encode_params& rParams )
{
...
ret = pSImager->setTargetImgBuffer(rParams.pDst)
&& pSImager->setTransform(rParams.transform)
&& pSImager->setCropROI(rParams.crop)
&& pSImager->setEncodeParam(
rParams.isSOI,
rParams.quality,
rParams.codecType,
false
)
&& pSImager->execute();
pSImager->destroyInstance();
pSImager = NULL;
//
if( !ret ) {
MY_LOGE("encode failed");
return UNKNOWN_ERROR;
}
...
}
12. 編碼下一張JPEG 或釋放資源。