cudacodec: ensure output frame resolution is display not coded size

pull/3470/head
cudawarped 2 years ago
parent ed1873bc2c
commit 82e2792ab5
  1. 8
      modules/cudacodec/src/video_parser.cpp
  2. 37
      modules/cudacodec/test/test_video.cpp

@ -122,16 +122,16 @@ int CUDAAPI cv::cudacodec::detail::VideoParser::HandleVideoSequence(void* userDa
newFormat.ulHeight = format->coded_height; newFormat.ulHeight = format->coded_height;
newFormat.fps = format->frame_rate.numerator / static_cast<float>(format->frame_rate.denominator); newFormat.fps = format->frame_rate.numerator / static_cast<float>(format->frame_rate.denominator);
newFormat.targetSz = thiz->videoDecoder_->getTargetSz(); newFormat.targetSz = thiz->videoDecoder_->getTargetSz();
newFormat.width = newFormat.targetSz.width ? newFormat.targetSz.width : format->coded_width;
newFormat.height = newFormat.targetSz.height ? newFormat.targetSz.height : format->coded_height;
newFormat.srcRoi = thiz->videoDecoder_->getSrcRoi(); newFormat.srcRoi = thiz->videoDecoder_->getSrcRoi();
if (newFormat.srcRoi.empty()) { if (newFormat.srcRoi.empty()) {
format->display_area.right = format->coded_width;
format->display_area.bottom = format->coded_height;
newFormat.displayArea = Rect(Point(format->display_area.left, format->display_area.top), Point(format->display_area.right, format->display_area.bottom)); newFormat.displayArea = Rect(Point(format->display_area.left, format->display_area.top), Point(format->display_area.right, format->display_area.bottom));
if (newFormat.targetSz.empty())
newFormat.targetSz = Size((format->display_area.right - format->display_area.left), (format->display_area.bottom - format->display_area.top));
} }
else else
newFormat.displayArea = newFormat.srcRoi; newFormat.displayArea = newFormat.srcRoi;
newFormat.width = newFormat.targetSz.width ? newFormat.targetSz.width : format->coded_width;
newFormat.height = newFormat.targetSz.height ? newFormat.targetSz.height : format->coded_height;
newFormat.targetRoi = thiz->videoDecoder_->getTargetRoi(); newFormat.targetRoi = thiz->videoDecoder_->getTargetRoi();
newFormat.ulNumDecodeSurfaces = min(!thiz->allowFrameDrop_ ? max(thiz->videoDecoder_->nDecodeSurfaces(), static_cast<int>(format->min_num_decode_surfaces)) : newFormat.ulNumDecodeSurfaces = min(!thiz->allowFrameDrop_ ? max(thiz->videoDecoder_->nDecodeSurfaces(), static_cast<int>(format->min_num_decode_surfaces)) :
format->min_num_decode_surfaces * 2, 32); format->min_num_decode_surfaces * 2, 32);

@ -58,6 +58,10 @@ PARAM_TEST_CASE(Scaling, cv::cuda::DeviceInfo, std::string, Size2f, Rect2f, Rect
{ {
}; };
struct DisplayResolution : testing::TestWithParam<cv::cuda::DeviceInfo>
{
};
PARAM_TEST_CASE(Video, cv::cuda::DeviceInfo, std::string) PARAM_TEST_CASE(Video, cv::cuda::DeviceInfo, std::string)
{ {
}; };
@ -223,6 +227,37 @@ CUDA_TEST_P(Scaling, Reader)
ASSERT_LT(mae, 2.35); ASSERT_LT(mae, 2.35);
} }
CUDA_TEST_P(DisplayResolution, Reader)
{
cv::cuda::setDevice(GetParam().deviceID());
std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../cv/video/1920x1080.avi";
const Rect displayArea(0, 0, 1920, 1080);
GpuMat frame;
{
// verify the output frame is the diplay size (1920x1080) and not the coded size (1920x1088)
cv::Ptr<cv::cudacodec::VideoReader> reader = cv::cudacodec::createVideoReader(inputFile);
reader->set(cudacodec::ColorFormat::GRAY);
ASSERT_TRUE(reader->nextFrame(frame));
const cudacodec::FormatInfo format = reader->format();
ASSERT_TRUE(format.displayArea == displayArea);
ASSERT_TRUE(frame.size() == displayArea.size() && frame.size() == format.targetSz);
}
{
// extra check to verify display frame has not been post-processed and is just a cropped version of the coded sized frame
cudacodec::VideoReaderInitParams params;
params.srcRoi = Rect(0, 0, 1920, 1088);
cv::Ptr<cv::cudacodec::VideoReader> readerCodedSz = cv::cudacodec::createVideoReader(inputFile, {}, params);
readerCodedSz->set(cudacodec::ColorFormat::GRAY);
GpuMat frameCodedSz;
ASSERT_TRUE(readerCodedSz->nextFrame(frameCodedSz));
const cudacodec::FormatInfo formatCodedSz = readerCodedSz->format();
const double err = cv::cuda::norm(frame, frameCodedSz(displayArea), NORM_INF);
ASSERT_TRUE(err == 0);
}
}
CUDA_TEST_P(Video, Reader) CUDA_TEST_P(Video, Reader)
{ {
cv::cuda::setDevice(GET_PARAM(0).deviceID()); cv::cuda::setDevice(GET_PARAM(0).deviceID());
@ -664,6 +699,8 @@ INSTANTIATE_TEST_CASE_P(CUDA_Codec, CheckSet, testing::Combine(
INSTANTIATE_TEST_CASE_P(CUDA_Codec, Scaling, testing::Combine( INSTANTIATE_TEST_CASE_P(CUDA_Codec, Scaling, testing::Combine(
ALL_DEVICES, testing::Values(VIDEO_SRC_SCALING), testing::Values(TARGET_SZ), testing::Values(SRC_ROI), testing::Values(TARGET_ROI))); ALL_DEVICES, testing::Values(VIDEO_SRC_SCALING), testing::Values(TARGET_SZ), testing::Values(SRC_ROI), testing::Values(TARGET_ROI)));
INSTANTIATE_TEST_CASE_P(CUDA_Codec, DisplayResolution, ALL_DEVICES);
#define VIDEO_SRC_R "highgui/video/big_buck_bunny.mp4", "cv/video/768x576.avi", "cv/video/1920x1080.avi", "highgui/video/big_buck_bunny.avi", \ #define VIDEO_SRC_R "highgui/video/big_buck_bunny.mp4", "cv/video/768x576.avi", "cv/video/1920x1080.avi", "highgui/video/big_buck_bunny.avi", \
"highgui/video/big_buck_bunny.h264", "highgui/video/big_buck_bunny.h265", "highgui/video/big_buck_bunny.mpg", \ "highgui/video/big_buck_bunny.h264", "highgui/video/big_buck_bunny.h265", "highgui/video/big_buck_bunny.mpg", \
"highgui/video/sample_322x242_15frames.yuv420p.libvpx-vp9.mp4", "highgui/video/sample_322x242_15frames.yuv420p.libaom-av1.mp4", \ "highgui/video/sample_322x242_15frames.yuv420p.libvpx-vp9.mp4", "highgui/video/sample_322x242_15frames.yuv420p.libaom-av1.mp4", \

Loading…
Cancel
Save