常规拍照也曝光多张,挑最后一张上传

PtzNew
Matthew 3 months ago
parent d939b8089e
commit 7624c2b249

@ -216,7 +216,7 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA
mResult = { 0 }; mResult = { 0 };
mLdr = ~0; mLdr = ~0;
mFinalLdr = 0; mFinalLdr = 0;
mFinalBurstCaptures = m_params.burstRawCapture == 0 ? 1 : m_params.burstCaptures; mFinalBurstCaptures = m_params.burstRawCapture == 0 ? m_params.burstCaptures : m_params.burstCaptures;
if (mFinalBurstCaptures == 0) if (mFinalBurstCaptures == 0)
{ {
mFinalBurstCaptures = 1; mFinalBurstCaptures = 1;
@ -1216,134 +1216,142 @@ void NdkCamera::onImageAvailable(AImageReader* reader)
else else
{ {
uint32_t burstCaptures = getBurstCaptures(); uint32_t burstCaptures = getBurstCaptures();
uint64_t ts = GetMicroTimeStamp();
size_t expectedTimes = mCaptureRequests.size() - 1;
if (burstCaptures == 0) if (burstCaptures == 0)
{ {
burstCaptures = 1; burstCaptures = 1;
} }
if (burstCaptures == 1) if (m_params.burstRawCapture == 0)
{ {
mstatus = AImageReader_acquireNextImage(reader, &image); while (1)
if (mstatus != AMEDIA_OK)
{ {
// https://stackoverflow.com/questions/67063562 mstatus = AImageReader_acquireNextImage(reader, &image);
if (mstatus != AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) if (mstatus != AMEDIA_OK)
{ {
if (mCaptureFrames.size() < burstCaptures) // https://stackoverflow.com/questions/67063562
if (mstatus != AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE)
{ {
XYLOG(XYLOG_SEVERITY_ERROR, "Capture AImageReader_acquireNextImage error: %d", mstatus); if (mCaptureFrames.size() < burstCaptures)
{
XYLOG(XYLOG_SEVERITY_ERROR, "Capture AImageReader_acquireNextImage error: %d", mstatus);
}
} }
break;
} }
return;
}
unsigned long long ts = GetMicroTimeStamp();
int32_t format; int32_t format;
mstatus = AImage_getFormat(image, &format); mstatus = AImage_getFormat(image, &format);
if (format == AIMAGE_FORMAT_YUV_420_888) cv::Mat frame;
{ if (format == AIMAGE_FORMAT_YUV_420_888)
int32_t width;
int32_t height;
mstatus = AImage_getWidth(image, &width);
mstatus = AImage_getHeight(image, &height);
int32_t y_pixelStride = 0;
int32_t u_pixelStride = 0;
int32_t v_pixelStride = 0;
AImage_getPlanePixelStride(image, 0, &y_pixelStride);
AImage_getPlanePixelStride(image, 1, &u_pixelStride);
AImage_getPlanePixelStride(image, 2, &v_pixelStride);
int32_t y_rowStride = 0;
int32_t u_rowStride = 0;
int32_t v_rowStride = 0;
AImage_getPlaneRowStride(image, 0, &y_rowStride);
AImage_getPlaneRowStride(image, 1, &u_rowStride);
AImage_getPlaneRowStride(image, 2, &v_rowStride);
uint8_t* y_data = 0;
uint8_t* u_data = 0;
uint8_t* v_data = 0;
int y_len = 0;
int u_len = 0;
int v_len = 0;
AImage_getPlaneData(image, 0, &y_data, &y_len);
AImage_getPlaneData(image, 1, &u_data, &u_len);
AImage_getPlaneData(image, 2, &v_data, &v_len);
if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width)
{
// already nv21
ConvertYUV21ToMat(y_data, width, height, mWidth, mHeight, camera_orientation,
camera_facing == ACAMERA_LENS_FACING_FRONT, m_params.orientation, mOneFrame);
}
else
{ {
// construct nv21 int32_t width;
uint8_t* nv21 = new uint8_t[width * height + width * height / 2]; int32_t height;
mstatus = AImage_getWidth(image, &width);
mstatus = AImage_getHeight(image, &height);
int32_t y_pixelStride = 0;
int32_t u_pixelStride = 0;
int32_t v_pixelStride = 0;
AImage_getPlanePixelStride(image, 0, &y_pixelStride);
AImage_getPlanePixelStride(image, 1, &u_pixelStride);
AImage_getPlanePixelStride(image, 2, &v_pixelStride);
int32_t y_rowStride = 0;
int32_t u_rowStride = 0;
int32_t v_rowStride = 0;
AImage_getPlaneRowStride(image, 0, &y_rowStride);
AImage_getPlaneRowStride(image, 1, &u_rowStride);
AImage_getPlaneRowStride(image, 2, &v_rowStride);
uint8_t* y_data = 0;
uint8_t* u_data = 0;
uint8_t* v_data = 0;
int y_len = 0;
int u_len = 0;
int v_len = 0;
AImage_getPlaneData(image, 0, &y_data, &y_len);
AImage_getPlaneData(image, 1, &u_data, &u_len);
AImage_getPlaneData(image, 2, &v_data, &v_len);
if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width)
{ {
// Y // already nv21
uint8_t* yptr = nv21; ConvertYUV21ToMat(y_data, width, height, mWidth, mHeight, camera_orientation,
for (int y = 0; y < height; y++) camera_facing == ACAMERA_LENS_FACING_FRONT, m_params.orientation, frame);
}
else
{
// construct nv21
uint8_t* nv21 = new uint8_t[width * height + width * height / 2];
{ {
const uint8_t* y_data_ptr = y_data + y_rowStride * y; // Y
for (int x = 0; x < width; x++) uint8_t* yptr = nv21;
for (int y = 0; y < height; y++)
{ {
yptr[0] = y_data_ptr[0]; const uint8_t* y_data_ptr = y_data + y_rowStride * y;
yptr++; for (int x = 0; x < width; x++)
y_data_ptr += y_pixelStride; {
yptr[0] = y_data_ptr[0];
yptr++;
y_data_ptr += y_pixelStride;
}
} }
}
// UV // UV
uint8_t* uvptr = nv21 + width * height; uint8_t* uvptr = nv21 + width * height;
for (int y = 0; y < height / 2; y++) for (int y = 0; y < height / 2; y++)
{
const uint8_t* v_data_ptr = v_data + v_rowStride * y;
const uint8_t* u_data_ptr = u_data + u_rowStride * y;
for (int x = 0; x < width / 2; x++)
{ {
uvptr[0] = v_data_ptr[0]; const uint8_t* v_data_ptr = v_data + v_rowStride * y;
uvptr[1] = u_data_ptr[0]; const uint8_t* u_data_ptr = u_data + u_rowStride * y;
uvptr += 2; for (int x = 0; x < width / 2; x++)
v_data_ptr += v_pixelStride; {
u_data_ptr += u_pixelStride; uvptr[0] = v_data_ptr[0];
uvptr[1] = u_data_ptr[0];
uvptr += 2;
v_data_ptr += v_pixelStride;
u_data_ptr += u_pixelStride;
}
} }
} }
}
ConvertYUV21ToMat(nv21, width, height,mWidth, mHeight, camera_orientation, ConvertYUV21ToMat(nv21, width, height,mWidth, mHeight, camera_orientation,
camera_facing == ACAMERA_LENS_FACING_FRONT, m_params.orientation, mOneFrame); camera_facing == ACAMERA_LENS_FACING_FRONT, m_params.orientation, frame);
delete[] nv21; delete[] nv21;
}
} }
} m_photoTaken = true;
m_photoTaken = true;
AImage_delete(image); AImage_delete(image);
std::shared_ptr<ACameraMetadata> result; bool captureCompleted = false;
bool captureCompleted = false; bool captureDispatchable = false;
bool captureDispatchable = false; m_locker.lock();
m_locker.lock(); if (!frame.empty())
if (!mCaptureResults.empty()) {
{ mOneFrame.push_back(frame);
captureCompleted = true; }
result = mCaptureResults[0]; if (mCaptureResults.size() == expectedTimes && mOneFrame.size() == expectedTimes)
} {
if (captureCompleted && !mCaptureDispatched) captureCompleted = true;
{ }
mCaptureDispatched = true; if (captureCompleted && !mCaptureDispatched)
captureDispatchable = true; {
} mCaptureDispatched = true;
m_locker.unlock(); captureDispatchable = true;
}
m_locker.unlock();
if (captureCompleted && captureDispatchable) if (captureCompleted && captureDispatchable)
{ {
XYLOG(XYLOG_SEVERITY_INFO,"onOneCapture from onImageAvailable"); XYLOG(XYLOG_SEVERITY_INFO,"onOneCapture from onImageAvailable");
camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session); camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session);
onOneCapture(mCharacteristics, result, mFinalLdr, ts - m_startTime, mOneFrame); FireOneCapture(ts);
// onOneCapture(mCharacteristics, result, mFinalLdr, ts - m_startTime, mOneFrame);
break;
}
} }
} }
else else
@ -1375,7 +1383,6 @@ void NdkCamera::onImageAvailable(AImageReader* reader)
bool captureCompleted = false; bool captureCompleted = false;
bool captureDispatchable = false; bool captureDispatchable = false;
size_t expectedTimes = mCaptureRequests.size() - 1;
m_locker.lock(); m_locker.lock();
captureCompleted = mCaptureResults.size() >= expectedTimes && mCaptureFrames.size() >= expectedTimes; captureCompleted = mCaptureResults.size() >= expectedTimes && mCaptureFrames.size() >= expectedTimes;
if (captureCompleted && !mCaptureDispatched) if (captureCompleted && !mCaptureDispatched)
@ -1808,11 +1815,11 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
size_t expectedTimes = mCaptureRequests.size() - 1; size_t expectedTimes = mCaptureRequests.size() - 1;
std::shared_ptr<ACameraMetadata> captureResult(pCopy, ACameraMetadata_free); std::shared_ptr<ACameraMetadata> captureResult(pCopy, ACameraMetadata_free);
if (expectedTimes == 1) if (m_params.burstRawCapture == 0)
{ {
m_locker.lock(); m_locker.lock();
mCaptureResults.push_back(captureResult); mCaptureResults.push_back(captureResult);
captureCompleted = !mOneFrame.empty(); captureCompleted = mCaptureFrames.size() >= expectedTimes && mCaptureResults.size() >= expectedTimes;
if (captureCompleted && !mCaptureDispatched) if (captureCompleted && !mCaptureDispatched)
{ {
mCaptureDispatched = true; mCaptureDispatched = true;
@ -1824,7 +1831,8 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
{ {
XYLOG(XYLOG_SEVERITY_INFO,"onOneCapture from onCaptureCompleted"); XYLOG(XYLOG_SEVERITY_INFO,"onOneCapture from onCaptureCompleted");
camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session); camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session);
onOneCapture(mCharacteristics, captureResult, mFinalLdr, ts - m_startTime, mOneFrame);
FireOneCapture(ts);
} }
} }
else else
@ -1848,6 +1856,33 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
} }
} }
void NdkCamera::FireOneCapture(uint64_t ts)
{
#ifdef OUTPUT_DBG_INFO
if (mWidth == 1920 && mOneFrame.size() > 1)
{
std::string dt = FormatLocalDateTime("%d%02d%02d%02d%02d%02d", ts / 1000);
std::vector<int> params;
params.push_back(cv::IMWRITE_JPEG_QUALITY);
params.push_back(50);
for (auto it = mOneFrame.cbegin(); it != mOneFrame.cend(); ++it)
{
std::string fileName = "/sdcard/com.xypower.mpapp/tmp/" + dt;
size_t idx = std::distance(mOneFrame.cbegin(), it);
std::shared_ptr<ACameraMetadata> result = mCaptureResults[idx];
CAPTURE_RESULT captureResult = { 0 };
EnumCameraResult(result.get(), captureResult);
fileName += "_" + mCameraId + "_" + std::to_string(captureResult.aeState) + "_" + std::to_string(idx) + ".jpg";
cv::imwrite(fileName, *it, params);
}
}
#endif
onOneCapture(mCharacteristics, mCaptureResults.back(), mFinalLdr, ts - m_startTime, mOneFrame.back());
}
void NdkCamera::FireBurstCapture() void NdkCamera::FireBurstCapture()
{ {
camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session); camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session);

@ -183,6 +183,7 @@ public:
void CopyPreviewRequest(ACaptureRequest* request, const ACameraMetadata* previewResult); void CopyPreviewRequest(ACaptureRequest* request, const ACameraMetadata* previewResult);
void FireBurstCapture(); void FireBurstCapture();
void FireOneCapture(uint64_t ts);
uint32_t GetLdr() const uint32_t GetLdr() const
{ {
@ -239,7 +240,7 @@ protected:
bool mCaptureDispatched; bool mCaptureDispatched;
CAPTURE_RESULT mResult; CAPTURE_RESULT mResult;
unsigned long long m_startTime; uint64_t m_startTime;
protected: protected:
@ -278,7 +279,8 @@ protected:
int32_t mFinalOutputFormat; int32_t mFinalOutputFormat;
std::vector<std::shared_ptr<AImage> > mCaptureFrames; std::vector<std::shared_ptr<AImage> > mCaptureFrames;
cv::Mat mOneFrame; // cv::Mat mOneFrame;
std::vector<cv::Mat> mOneFrame;
std::vector<std::vector<uint8_t> > mRawFrames; std::vector<std::vector<uint8_t> > mRawFrames;
// AImageReader* image_reader; // AImageReader* image_reader;

Loading…
Cancel
Save