基于Android Qcom Display学习(九)的示例再补充一点如何或者previewbuffer
/frameworks/base/core/jni/android_hardware_Camera.cpp
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
camera->setListener(context); //class JNICameraContext: public CameraListener
JNICamreraContext监听类继承自CameraListener,来监听处理底层Camera回调函数传过来的数据和消息
//android_hardware_Camera.cpp
class CameraCallback: public CameraListener{
public:
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
camera_frame_metadata_t *metadata);
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
virtual void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle);
virtual void postRecordingFrameHandleTimestampBatch(const std::vector<nsecs_t>& timestamps,
const std::vector<native_handle_t*>& handles);
};
void CameraCallback::postData(int32_t msgType, const sp<IMemory> &dataPtr,
camera_frame_metadata_t * metadata){
//JNNCameraContext::copyAndPost
//Vector<jbyteArray> mCallbackBuffers;
//jbyteArray obj = NULL; post to app
ALOGD("jerry postData success");
if(dataPtr != NULL && metadata != NULL){
ssize_t offset;
size_t size;
sp<IMemoryHeap> heap = dataPtr->getMemory(&offset, &size);
uint8_t *heapBase = (uint8_t*)heap->base();
if (msgType == CAMERA_MSG_PREVIEW_FRAME ) {
if(count == 10){
int fd = ::open("data/misc/camera/previewbuffer.yuv", O_RDWR | O_CREAT, 0777);
if(fd < 0) {
ALOGD("dump: failed to open file");
return;
}
::write(fd, heapBase, size);
::close(fd);
}else
count ++;
}
}
}
//not used now just compile
void CameraCallback::notify(int32_t msgType, int32_t ext1, int32_t ext2){
if(msgType == 0 || ext1 == 0 || ext2 ==0)
ALOGD("compile");
}
void CameraCallback::postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr){
if(timestamp == 0 || msgType == 0 || dataPtr == nullptr)
ALOGD("compile");
}
void CameraCallback::postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle){
if(timestamp == 0 || handle == nullptr)
ALOGD("compile");
}
void CameraCallback::postRecordingFrameHandleTimestampBatch(const std::vector<nsecs_t>& timestamps,
const std::vector<native_handle_t*>& handles){
if(timestamps.empty() || handles.empty())
ALOGD("compile");
}
int main(){
...
mCamera->startPreview();
//CallbackProcessor.cpp
mCamera->setPreviewCallbackFlags(5);//CAMERA_FRAME_CALLBACK_FLAG_CAMERA
sp<CameraCallback> context = new CameraCallback();
mCamera->setListener(context);
IPCThreadState::self()->joinThreadPool();
return 0;
}
将dump出来的数据,从Chromtix工具打开,填写stride,可以看到解析出图像,但是为什么不是色彩的?看起来黑白的像是Raw图,msgType是CAMERA_MSG_PREVIEW_FRAME(0x0010),callback回来的看msgType也并非是CAMERA_MSG_RAW_IMAGE(0x0080)所对应的Raw图,看请求的是YCbCr_420_SP对应(NV21) format,于是使用YuvViewer使用NV21的格式进行解析后图片颜色正常,是个钥匙串小老鼠。