I'm just starting with IPP and at the moment I just need to resize interlaced video frames which are in RGB32 format.
I do NOT want to deinterlace the frames. I just want to resize, but preserve the interlaced nature of each frame. So for example 1080i could be resized to 480i. Conceptually, this might mean separating the odd and even lines from each frame to produce two independent field images, then resizing each field image separately, and then bringing them back together to produce the final interlaced resized frame.
The IPP help page
https://software.intel.com/en-us/node/504353#RESIZING_WHOLE_IMAGE
has example code and seems to be a good starting point for resizing each video frame, but this assumes that the frame is progressive.
How can I resize an interlaced frame using IPP ?
Resizing each field as a progressive frame will introduce a small error. You need to shift each field a little. Current versions of ipp lost the ability of scaling and moving a frame in the same operation, but you can go back to ipp version 8.2 to get back ippiResizeSqrPixel that can do it. Or you can scale and then shift with CopySubpix. ippiResizeSqrPixel has a small bug of it's own that needs to be corrected:
img scale_ipp_resize_sqr_interlaced(img const& input, int outw, int outh) { img result(outw, outh); int interpolation = IPPI_INTER_LINEAR | IPPI_ANTIALIASING; double xFactor = (double)result.width / input.width; double yFactor = (double)result.height / input.height; double xShiftCorrector = xFactor / 2; double yShiftCorrector = yFactor / 2; int size{}; Check(ipp82_ippiResizeGetBufSize({ 0, 0, input.width, input.height / 2 }, { 0, 0, result.width, result.height / 2 }, ippC1, interpolation, &size)); Ipp8u* pBuffer = ippsMalloc_8u(size); ON_BLOCK_EXIT([&] { ippsFree(pBuffer); }); Check(ippiResizeSqrPixel_8u_C1R( input.data.data(), { input.width, input.height / 2 }, input.width * 2, { 0, 0, input.width, input.height / 2 }, result.data.data(), result.width * 2, { 0, 0, result.width, result.height / 2 }, xFactor, yFactor, xShiftCorrector, yShiftCorrector + (1 - yFactor) / 4, interpolation, pBuffer )); Check(ippiResizeSqrPixel_8u_C1R( input.data.data() + input.width, { input.width, input.height / 2 }, input.width * 2, { 0, 0, input.width, input.height / 2 }, result.data.data() + result.width, result.width * 2, { 0, 0, result.width, result.height / 2 }, xFactor, yFactor, xShiftCorrector, yShiftCorrector - (1 - yFactor) / 4, interpolation, pBuffer )); return result; }
連結已複製
IPP does not support video resize any more. Media SDK supports video resize. You may ask your question in media SDK support forum here https://software.intel.com/en-us/forums/intel-media-sdk. Thanks!
> IPP does not support video resize any more.
Progressive video frames just images, so they are surely resizable using IPP. For example, resizing NV12 video frames using ResizeYUV420Lanczos "Changes the size of the NV12 image by interpolation with the Lanczos filter" - from the IPP 2017 Update 2 docs:
https://software.intel.com/en-us/node/504389
Do you mean instead that there is no functionality in IPP to resize specifically INTERLACED input video frames to produce INTERLACED output video frames ?
Resizing each field as a progressive frame will introduce a small error. You need to shift each field a little. Current versions of ipp lost the ability of scaling and moving a frame in the same operation, but you can go back to ipp version 8.2 to get back ippiResizeSqrPixel that can do it. Or you can scale and then shift with CopySubpix. ippiResizeSqrPixel has a small bug of it's own that needs to be corrected:
img scale_ipp_resize_sqr_interlaced(img const& input, int outw, int outh) { img result(outw, outh); int interpolation = IPPI_INTER_LINEAR | IPPI_ANTIALIASING; double xFactor = (double)result.width / input.width; double yFactor = (double)result.height / input.height; double xShiftCorrector = xFactor / 2; double yShiftCorrector = yFactor / 2; int size{}; Check(ipp82_ippiResizeGetBufSize({ 0, 0, input.width, input.height / 2 }, { 0, 0, result.width, result.height / 2 }, ippC1, interpolation, &size)); Ipp8u* pBuffer = ippsMalloc_8u(size); ON_BLOCK_EXIT([&] { ippsFree(pBuffer); }); Check(ippiResizeSqrPixel_8u_C1R( input.data.data(), { input.width, input.height / 2 }, input.width * 2, { 0, 0, input.width, input.height / 2 }, result.data.data(), result.width * 2, { 0, 0, result.width, result.height / 2 }, xFactor, yFactor, xShiftCorrector, yShiftCorrector + (1 - yFactor) / 4, interpolation, pBuffer )); Check(ippiResizeSqrPixel_8u_C1R( input.data.data() + input.width, { input.width, input.height / 2 }, input.width * 2, { 0, 0, input.width, input.height / 2 }, result.data.data() + result.width, result.width * 2, { 0, 0, result.width, result.height / 2 }, xFactor, yFactor, xShiftCorrector, yShiftCorrector - (1 - yFactor) / 4, interpolation, pBuffer )); return result; }
