[G-API] Added Y, UV accessors for cv::MediaFrame#19325
Conversation
37060c6 to
2387594
Compare
ef03dd7 to
033ac49
Compare
|
Consider to use |
TolyaTalamanov
left a comment
There was a problem hiding this comment.
Good, but let's discuss adapter logic locally
ae01eb2 to
4102140
Compare
4102140 to
f346d64
Compare
TolyaTalamanov
left a comment
There was a problem hiding this comment.
LGTM 👍
Great, thanks!
b44774c to
d222419
Compare
| }; | ||
|
|
||
| G_API_OP(GY, <GMat(GFrame)>, "org.opencv.streaming.Y") { | ||
| static GMatDesc outMeta(const GFrameDesc frameDesc) { |
| }; | ||
|
|
||
| G_API_OP(GUV, <GMat(GFrame)>, "org.opencv.streaming.UV") { | ||
| static GMatDesc outMeta(const GFrameDesc frameDesc) { |
|
|
||
| /** @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.
is. "shall be" assumes some requirement or expectation set, but it is not the case.
|
|
||
| /** @brief Extracts UV plane from media frame. | ||
|
|
||
| Output image shall be 8-bit 2-channels image of @ref CV_8UC2. |
| { | ||
| 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.
This looks weird, why do we need a callback like this here?
There was a problem hiding this comment.
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.
| 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.
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.
Ah you only do it to obtain meta early -- then I'd move it to that point.
There was a problem hiding this comment.
Also, if you'll do this, please take care of concurrency.
There was a problem hiding this comment.
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.
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.
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.
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.
We don't throw exception in the OCV BGR kernel also..
There was a problem hiding this comment.
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.
There is no need in explicit anymore as the constructor takes >1 parameter
| { | ||
| 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.
"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)
71fab18 to
b0d66e0
Compare
dmatveev
left a comment
There was a problem hiding this comment.
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.
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.
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.
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"); |
| 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 " |
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.