mirror of
https://github.com/opencv/opencv.git
synced 2025-07-23 21:16:58 +08:00
Merge pull request #26698 from warped-rudi:mediandk2
AndroidMediaNdkVideoWriter pixel format enhancement #26698 * videoio(Android): Add source pixel formats RGBA and GRAY to AndroidMediaNdkVideoWriter Let AndroidMediaNdkVideoWriter::write() deduce source pixel format from matrix type: CV_8UC3 -> BGR (as before) CV_8UC4 -> RGBA (use in conjunction with CvCameraViewFrame) CV_8UC1 -> GRAY * samples/android/video-recorder: Send images to VideoWriter in RGBA format ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
parent
f65006eee1
commit
a6f72f813d
@ -551,10 +551,12 @@ public:
|
||||
}
|
||||
|
||||
Mat image = image_.getMat();
|
||||
if (CV_8UC3 != image.type() || image.cols > width || image.rows > height) {
|
||||
if (image.cols > width || image.rows > height ||
|
||||
(CV_8UC1 != image.type() && CV_8UC3 != image.type() && CV_8UC4 != image.type())) {
|
||||
LOGE(
|
||||
"Expected input to be a mat of maximum %d x %d of type CV_8UC3 (%d), but received %d x %d of type: %d",
|
||||
width, height, CV_8UC3,
|
||||
"Expected input to be a mat of maximum %d x %d of type CV_8UC1, CV_8UC3 or CV_8UC4"
|
||||
" (%d, %d, %d), but received %d x %d of type %d",
|
||||
width, height, CV_8UC1, CV_8UC3, CV_8UC4,
|
||||
image.cols, image.rows, image.type()
|
||||
);
|
||||
return;
|
||||
@ -564,33 +566,45 @@ public:
|
||||
ANativeWindow_Buffer buffer;
|
||||
if (0 != ANativeWindow_lock(surface, &buffer, NULL)) {
|
||||
LOGE("Failed to lock the surface");
|
||||
} else {
|
||||
if (AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM == buffer.format) {
|
||||
Mat bufferMat(image.rows, image.cols, CV_8UC4, buffer.bits, buffer.stride * 4);
|
||||
cvtColor(image, bufferMat, CV_BGR2RGBA);
|
||||
} else {
|
||||
LOGE("Unknow surface buffer format: %u", buffer.format);
|
||||
}
|
||||
|
||||
ANativeWindow_unlockAndPost(surface);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
LOGV("[write] image: %d x %d", image.cols, image.rows);
|
||||
|
||||
//OpenCV don't support RGB to NV12 so we need to connvert to YV12 and then manually changed it to NV12
|
||||
if (AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM == buffer.format) {
|
||||
Mat bufferMat(image.rows, image.cols, CV_8UC4, buffer.bits, buffer.stride * 4);
|
||||
switch (image.type()) {
|
||||
case CV_8UC4: image.copyTo(bufferMat); break;
|
||||
case CV_8UC3: cvtColor(image, bufferMat, CV_BGR2RGBA); break;
|
||||
case CV_8UC1: cvtColor(image, bufferMat, CV_GRAY2RGBA); break;
|
||||
}
|
||||
} else {
|
||||
LOGE("Unknown surface buffer format: 0x%x", buffer.format);
|
||||
}
|
||||
|
||||
ANativeWindow_unlockAndPost(surface);
|
||||
#else
|
||||
//OpenCV doesn't support RGB to NV12 so we need to convert to YV12 and then manually changed it to NV12
|
||||
Mat imageYV12;
|
||||
cvtColor(image, imageYV12, CV_BGR2YUV_YV12);
|
||||
switch (image.type()) {
|
||||
case CV_8UC4: cvtColor(image, imageYV12, CV_RGBA2YUV_YV12); break;
|
||||
case CV_8UC3: cvtColor(image, imageYV12, CV_BGR2YUV_YV12); break;
|
||||
case CV_8UC1: imageYV12.create(image.rows + image.rows/2, image.cols, CV_8UC1);
|
||||
image.copyTo(imageYV12.rowRange(0, image.rows));
|
||||
imageYV12.rowRange(image.rows, imageYV12.rows) = 128;
|
||||
break;
|
||||
}
|
||||
|
||||
//convert from YV12 to NV12
|
||||
size_t yPlaneSize = width * height;
|
||||
size_t vPlaneSize = yPlaneSize / 4;
|
||||
if (image.type() != CV_8UC1) {
|
||||
size_t yPlaneSize = width * height;
|
||||
size_t vPlaneSize = yPlaneSize / 4;
|
||||
|
||||
Mat channels[2] = {
|
||||
Mat( vPlaneSize, 1, CV_8UC1, imageYV12.ptr() + yPlaneSize + vPlaneSize ).clone(),
|
||||
Mat( vPlaneSize, 1, CV_8UC1, imageYV12.ptr() + yPlaneSize ).clone()
|
||||
};
|
||||
Mat vuMat( vPlaneSize, 1, CV_8UC2, imageYV12.ptr() + yPlaneSize );
|
||||
merge(channels, 2, vuMat);
|
||||
Mat channels[2] = {
|
||||
Mat( vPlaneSize, 1, CV_8UC1, imageYV12.ptr() + yPlaneSize + vPlaneSize ).clone(),
|
||||
Mat( vPlaneSize, 1, CV_8UC1, imageYV12.ptr() + yPlaneSize ).clone()
|
||||
};
|
||||
Mat vuMat( vPlaneSize, 1, CV_8UC2, imageYV12.ptr() + yPlaneSize );
|
||||
merge(channels, 2, vuMat);
|
||||
}
|
||||
|
||||
writeBytes( imageYV12.ptr(), imageYV12.rows * imageYV12.cols );
|
||||
#endif
|
||||
|
@ -164,16 +164,15 @@ public class RecorderActivity extends CameraActivity implements CvCameraViewList
|
||||
{
|
||||
Log.d(TAG, "Camera frame arrived");
|
||||
|
||||
Mat rgbMat = inputFrame.rgba();
|
||||
mVideoFrame = inputFrame.rgba();
|
||||
|
||||
Log.d(TAG, "Size: " + rgbMat.width() + "x" + rgbMat.height());
|
||||
Log.d(TAG, "Size: " + mVideoFrame.width() + "x" + mVideoFrame.height());
|
||||
|
||||
if (mVideoWriter != null && mVideoWriter.isOpened()) {
|
||||
Imgproc.cvtColor(rgbMat, mVideoFrame, Imgproc.COLOR_RGBA2BGR);
|
||||
mVideoWriter.write(mVideoFrame);
|
||||
}
|
||||
|
||||
return rgbMat;
|
||||
return mVideoFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user