CARVIEW |
Navigation Menu
-
-
Notifications
You must be signed in to change notification settings - Fork 56.2k
[G-API] Added Y, UV accessors for cv::MediaFrame #19325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
37060c6
to
2387594
Compare
ef03dd7
to
033ac49
Compare
Consider to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, but let's discuss adapter logic locally
ae01eb2
to
4102140
Compare
4102140
to
f346d64
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
Great, thanks!
b44774c
to
d222419
Compare
@@ -20,6 +20,19 @@ G_API_OP(GBGR, <GMat(GFrame)>, "org.opencv.streaming.BGR") | |||
static GMatDesc outMeta(const GFrameDesc& in) { return GMatDesc{CV_8U, 3, in.size}; } | |||
}; | |||
|
|||
G_API_OP(GY, <GMat(GFrame)>, "org.opencv.streaming.Y") { | |||
static GMatDesc outMeta(const GFrameDesc frameDesc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
}; | ||
|
||
G_API_OP(GUV, <GMat(GFrame)>, "org.opencv.streaming.UV") { | ||
static GMatDesc outMeta(const GFrameDesc frameDesc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -29,6 +42,25 @@ G_API_OP(GBGR, <GMat(GFrame)>, "org.opencv.streaming.BGR") | |||
*/ | |||
GAPI_EXPORTS cv::GMat BGR(const cv::GFrame& in); | |||
|
|||
/** @brief Extracts Y plane from media frame. | |||
|
|||
Output image shall be 8-bit 1-channel image of @ref CV_8UC1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is
. "shall be" assumes some requirement or expectation set, but it is not the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
|
||
/** @brief Extracts UV plane from media frame. | ||
|
||
Output image shall be 8-bit 2-channels image of @ref CV_8UC2. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2-channel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
{ | ||
explicit RMatMediaAdapterBGR(const cv::MediaFrame& frame) : m_frame(frame) { }; | ||
explicit RMatMediaFrameAdapter(const cv::MediaFrame& frame, | ||
std::function<cv::Mat(const GFrameDesc&, const cv::MediaFrame::View&)> frameViewToMat) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks weird, why do we need a callback like this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got the idea after reviewing the rest of this code. I'd recommend to give this std::function
a name (right within this class). See how our kernels are implemented in e.g. Fluid backend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
m_frameViewToMat(frameViewToMat) | ||
{ | ||
const auto& d = m_frame.desc(); | ||
const auto& fv = m_frame.access(cv::MediaFrame::Access::R); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd delay this to the actual access
- why do we map MediaFrame's data immediately?
Is there a performance benefit in our case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah you only do it to obtain meta early -- then I'd move it to that point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if you'll do this, please take care of concurrency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this part.
Implemented retrieving of meta as discussed internally.
auto ptr = reinterpret_cast<uchar*>(view.ptr[0]); | ||
auto stride = view.stride[0]; | ||
auto fv = m_frame.access(a == cv::RMat::Access::R ? cv::MediaFrame::Access::R | ||
: cv::MediaFrame::Access::W); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no guarantee in only R
and W
being used exclusively, there may be RW
introduced one day.
This code will break then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added mapping lamda, but it throws exception if cv::RMat::Access
is not R
or W
for now.
auto view = frame.access(cv::MediaFrame::Access::R); | ||
cv::Mat tmp_bgr(desc.size, CV_8UC3, view.ptr[0], view.stride[0]); | ||
cv::Mat yuv; | ||
cvtColor(tmp_bgr, yuv, cv::COLOR_BGR2YUV_I420); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of BGR()
accessor called on an NV12 MediaFrame, we simply throw an exception (except some target platform where that conversion is implemented in firmware).
Since in case of Y()
accessor we actually do the conversion (on CPU - what is debatable for high resolutions we target to), I'd align the behavior between the accessors.
Also, since the on-the-fly conversion is costly, I'd put a warning but only once per actor - not for every frame we process. You might want to look at std::call_once
for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't throw exception in the OCV BGR kernel also..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added warning for every accessor in case of non-consistent input format.
Warning is thrown only once per frame.
0ab881f
to
71fab18
Compare
using MapDescF = std::function<cv::GMatDesc(const GFrameDesc&)>; | ||
using MapDataF = std::function<cv::Mat(const GFrameDesc&, const cv::MediaFrame::View&)>; | ||
|
||
explicit RMatMediaFrameAdapter(const cv::MediaFrame& frame, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need in explicit
anymore as the constructor takes >1 parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
{ | ||
std::call_once(m_warnFlag, | ||
[](){ | ||
GAPI_LOG_WARNING(NULL, "On-fly conversion from NV12 to BGR will be happened."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"On-the-fly", "will happen". I'd also put a recommendation here so user could figure out how to change his code to avoid that (and briefly explain why it is a problem)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
71fab18
to
b0d66e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please merge this now and fix the text later.
cv::util::throw_error(std::logic_error("cv::RMat::Access::R or " | ||
"cv::RMat::Access::W can only be mapped to cv::MediaFrame::Access!")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this text is misleading and it'd be enough to only put an assert here, saying that only R/W are accepted.
Please do it later (not in this PR).
std::call_once(m_warnFlag, | ||
[](){ | ||
GAPI_LOG_WARNING(NULL, "\nOn-the-fly conversion from NV12 to BGR will happen.\n" | ||
"Conversion may cost a lot for images with high resolution.\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cost a lot -> may be costly.
Again, please fix it later.
GAPI_LOG_WARNING(NULL, "\nOn-the-fly conversion from NV12 to BGR will happen.\n" | ||
"Conversion may cost a lot for images with high resolution.\n" | ||
"To retrieve cv::Mat-s from NV12 cv::MediaFrame for free, you may use " | ||
"cv::gapi::streaming::Y and cv::gapi::streaming::UV accessors.\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be misleading too since Y
and UV
are working at cv::GMat
level (I mean, for user), there's no Mats etc.
"Conversion may cost a lot for images with high resolution.\n" | ||
"To retrieve cv::Mat from BGR cv::MediaFrame for free, you may use " | ||
"cv::gapi::streaming::BGR accessor.\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here
GAPI_LOG_WARNING(NULL, "\nOn-the-fly conversion from BGR to NV12 UV plane will " | ||
"happen.\n" | ||
"Conversion may cost a lot for images with high resolution.\n" | ||
"To retrieve cv::Mat from BGR cv::MediaFrame for free, you may use " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here.
Thanks a lot! |
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.
This PR adds two operations to retrieve Y and UV GMat-s from GFrame.