VPM: Assign correct required size for odd size destination frame.
Updates to spatial resampler unittest. Review URL: https://webrtc-codereview.appspot.com/660006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2444 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
bd7aeba8fb
commit
5567ebfd1f
@ -54,13 +54,17 @@ int Scaler::Scale(const uint8_t* src_frame,
|
||||
return -2;
|
||||
|
||||
// Making sure that destination frame is of sufficient size
|
||||
int required_dst_size = dst_width_ * dst_height_ * 3 / 2;
|
||||
int dst_half_width = (dst_width_ + 1) >> 1;
|
||||
int dst_half_height = (dst_height_ + 1) >> 1;
|
||||
int required_dst_size = dst_width_ * dst_height_ + 2 * (dst_half_width *
|
||||
dst_half_height);
|
||||
if (dst_frame && required_dst_size > dst_size) {
|
||||
// allocated buffer is too small
|
||||
delete [] dst_frame;
|
||||
dst_frame = NULL;
|
||||
}
|
||||
if (dst_frame == NULL) {
|
||||
// TODO(mikhal): align this buffer to 16 bytes.
|
||||
dst_frame = new uint8_t[required_dst_size];
|
||||
dst_size = required_dst_size;
|
||||
}
|
||||
@ -72,8 +76,6 @@ int Scaler::Scale(const uint8_t* src_frame,
|
||||
const uint8_t* src_uplane = src_frame + src_width_ * src_height_;
|
||||
const uint8_t* src_vplane = src_uplane + src_half_width * src_half_height;
|
||||
|
||||
int dst_half_width = (dst_width_ + 1) >> 1;
|
||||
int dst_half_height = (dst_height_ + 1) >> 1;
|
||||
uint8_t* dst_yplane = dst_frame;
|
||||
uint8_t* dst_uplane = dst_frame + dst_width_ * dst_height_;
|
||||
uint8_t* dst_vplane = dst_uplane + dst_half_width * dst_half_height;
|
||||
|
@ -74,16 +74,19 @@ VPMSimpleSpatialResampler::ResampleFrame(const VideoFrame& inFrame,
|
||||
}
|
||||
|
||||
// Setting scaler
|
||||
//TODO: Modify scaler types
|
||||
// TODO(mikhal/marpan): Should we allow for setting the filter mode in
|
||||
// _scale.Set() with |_resamplingMode|?
|
||||
int retVal = 0;
|
||||
retVal = _scaler.Set(inFrame.Width(), inFrame.Height(),
|
||||
_targetWidth, _targetHeight, kI420, kI420, kScaleBox);
|
||||
if (retVal < 0)
|
||||
return retVal;
|
||||
|
||||
|
||||
// Disabling cut/pad for now - only scaling.
|
||||
int requiredSize = (WebRtc_UWord32)(_targetWidth * _targetHeight * 3 >> 1);
|
||||
int target_half_width = (_targetWidth + 1) >> 1;
|
||||
int target_half_height = (_targetHeight + 1) >> 1;
|
||||
int requiredSize = static_cast<int>(_targetWidth * _targetHeight + 2 *
|
||||
(target_half_width * target_half_height));
|
||||
outFrame.VerifyAndAllocate(requiredSize);
|
||||
outFrame.SetTimeStamp(inFrame.TimeStamp());
|
||||
outFrame.SetWidth(_targetWidth);
|
||||
|
@ -18,9 +18,14 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
void TestSize(VideoFrame& sourceFrame,
|
||||
WebRtc_UWord32 targetWidth, WebRtc_UWord32 targetHeight,
|
||||
WebRtc_UWord32 mode, VideoProcessingModule *vpm);
|
||||
// The |sourceFrame| is scaled to |target_width|,|target_height|, using the
|
||||
// filter mode set to |mode|. The |expected_psnr| is used to verify basic
|
||||
// quality when the resampled frame is scaled back up/down to the
|
||||
// original/source size. |expected_psnr| is set to be ~0.1/0.05dB lower than
|
||||
// actual PSNR verified under the same conditions.
|
||||
void TestSize(const VideoFrame& sourceFrame, int target_width,
|
||||
int target_height, int mode, double expected_psnr,
|
||||
VideoProcessingModule* vpm);
|
||||
|
||||
VideoProcessingModuleTest::VideoProcessingModuleTest() :
|
||||
_vpm(NULL),
|
||||
@ -275,26 +280,22 @@ TEST_F(VideoProcessingModuleTest, Resampler)
|
||||
// initiate test timer
|
||||
t0 = TickTime::Now();
|
||||
|
||||
// kFastRescaling
|
||||
_vpm->SetInputFrameResampleMode(kFastRescaling);
|
||||
// TESTING DIFFERENT SIZES
|
||||
TestSize(sourceFrame, 100, 50, 1, _vpm); // Cut, decimation 1x, interpolate
|
||||
TestSize(sourceFrame, 352/2, 288/2, 1, _vpm); // Even decimation
|
||||
TestSize(sourceFrame, 352, 288, 1, _vpm); // No resampling
|
||||
TestSize(sourceFrame, 2*352, 2*288,1, _vpm); // Even upsampling
|
||||
TestSize(sourceFrame, 400, 256, 1, _vpm); // Upsampling 1.5x and cut
|
||||
TestSize(sourceFrame, 960, 720, 1, _vpm); // Upsampling 3.5x and cut
|
||||
TestSize(sourceFrame, 1280, 720, 1, _vpm); // Upsampling 4x and cut
|
||||
// Test scaling to different sizes: source is of |width|/|height| = 352/288.
|
||||
// Scaling mode in VPM is currently fixed to kScaleBox (mode = 3).
|
||||
TestSize(sourceFrame, 100, 50, 3, 24.0, _vpm);
|
||||
TestSize(sourceFrame, 352/4, 288/4, 3, 25.2, _vpm);
|
||||
TestSize(sourceFrame, 352/2, 288/2, 3, 28.1, _vpm);
|
||||
TestSize(sourceFrame, 352, 288, 3, -1, _vpm); // no resampling.
|
||||
TestSize(sourceFrame, 2*352, 2*288, 3, 32.2, _vpm);
|
||||
TestSize(sourceFrame, 400, 256, 3, 31.3, _vpm);
|
||||
TestSize(sourceFrame, 480, 640, 3, 32.15, _vpm);
|
||||
TestSize(sourceFrame, 960, 720, 3, 32.2, _vpm);
|
||||
TestSize(sourceFrame, 1280, 720, 3, 32.15, _vpm);
|
||||
// Upsampling to odd size.
|
||||
TestSize(sourceFrame, 501, 333, 3, 32.05, _vpm);
|
||||
// Downsample to odd size.
|
||||
TestSize(sourceFrame, 281, 175, 3, 29.3, _vpm);
|
||||
|
||||
// kBiLinear
|
||||
_vpm->SetInputFrameResampleMode(kBiLinear);
|
||||
// TESTING DIFFERENT SIZES
|
||||
TestSize(sourceFrame, 352/4, 288/4, 2, _vpm);
|
||||
TestSize(sourceFrame, 352/2, 288/2, 2, _vpm);
|
||||
TestSize(sourceFrame, 2*352, 2*288,2, _vpm);
|
||||
TestSize(sourceFrame, 480, 640, 2, _vpm);
|
||||
TestSize(sourceFrame, 960, 720, 2, _vpm);
|
||||
TestSize(sourceFrame, 1280, 720, 2, _vpm);
|
||||
// stop timer
|
||||
t1 = TickTime::Now();
|
||||
accTicks += t1 - t0;
|
||||
@ -315,32 +316,81 @@ TEST_F(VideoProcessingModuleTest, Resampler)
|
||||
static_cast<int>(minRuntime));
|
||||
}
|
||||
|
||||
void TestSize(VideoFrame& sourceFrame, WebRtc_UWord32 targetWidth,
|
||||
WebRtc_UWord32 targetHeight,
|
||||
WebRtc_UWord32 mode, VideoProcessingModule *vpm)
|
||||
{
|
||||
VideoFrame *outFrame = NULL;
|
||||
void TestSize(const VideoFrame& source_frame, int target_width,
|
||||
int target_height, int mode, double expected_psnr,
|
||||
VideoProcessingModule* vpm) {
|
||||
int source_width = source_frame.Width();
|
||||
int source_height = source_frame.Height();
|
||||
VideoFrame* out_frame = NULL;
|
||||
|
||||
ASSERT_EQ(VPM_OK, vpm->SetTargetResolution(target_width, target_height, 30));
|
||||
ASSERT_EQ(VPM_OK, vpm->PreprocessFrame(&source_frame, &out_frame));
|
||||
|
||||
// If the frame was resampled (scale changed) then:
|
||||
// (1) verify the new size and write out processed frame for viewing.
|
||||
// (2) scale the resampled frame (|out_frame|) back to the original size and
|
||||
// compute PSNR relative to |source_frame| (for automatic verification).
|
||||
// (3) write out the processed frame for viewing.
|
||||
if (target_width != static_cast<int>(source_width) ||
|
||||
target_height != static_cast<int>(source_height)) {
|
||||
int target_half_width = (target_width + 1) >> 1;
|
||||
int target_half_height = (target_height + 1) >> 1;
|
||||
int required_size_resampled = target_width * target_height +
|
||||
2 * (target_half_width * target_half_height);
|
||||
ASSERT_EQ(required_size_resampled, static_cast<int>(out_frame->Length()));
|
||||
|
||||
// Write the processed frame to file for visual inspection.
|
||||
std::ostringstream filename;
|
||||
filename << webrtc::test::OutputPath() << "Resampler_"<< mode << "_" <<
|
||||
targetWidth << "x" << targetHeight << "_30Hz_P420.yuv";
|
||||
// TODO(kjellander): Add automatic verification of these output files:
|
||||
"from_" << source_width << "x" << source_height << "_to_" <<
|
||||
target_width << "x" << target_height << "_30Hz_P420.yuv";
|
||||
std::cout << "Watch " << filename.str() << " and verify that it is okay."
|
||||
<< std::endl;
|
||||
FILE* standAloneFile = fopen(filename.str().c_str(), "wb");
|
||||
ASSERT_EQ(VPM_OK, vpm->SetTargetResolution(targetWidth, targetHeight, 30));
|
||||
ASSERT_EQ(VPM_OK, vpm->PreprocessFrame(&sourceFrame, &outFrame));
|
||||
// Length should be updated only if frame was resampled
|
||||
if (targetWidth != sourceFrame.Width() ||
|
||||
targetHeight != sourceFrame.Height()) {
|
||||
ASSERT_EQ((targetWidth * targetHeight * 3 / 2), outFrame->Length());
|
||||
// Write to file for visual inspection
|
||||
if (fwrite(outFrame->Buffer(), 1,
|
||||
outFrame->Length(), standAloneFile) != outFrame->Length()) {
|
||||
FILE* stand_alone_file = fopen(filename.str().c_str(), "wb");
|
||||
if (fwrite(out_frame->Buffer(), 1,
|
||||
out_frame->Length(), stand_alone_file) != out_frame->Length()) {
|
||||
fprintf(stderr, "Failed to write frame for scaling to width/height: "
|
||||
" %d %d \n", target_width, target_height);
|
||||
return;
|
||||
}
|
||||
outFrame->Free();
|
||||
fclose(stand_alone_file);
|
||||
|
||||
VideoFrame resampled_source_frame;
|
||||
resampled_source_frame.CopyFrame(*out_frame);
|
||||
|
||||
// Scale |resampled_source_frame| back to original/source size.
|
||||
ASSERT_EQ(VPM_OK, vpm->SetTargetResolution(source_width,
|
||||
source_height,
|
||||
30));
|
||||
ASSERT_EQ(VPM_OK, vpm->PreprocessFrame(&resampled_source_frame,
|
||||
&out_frame));
|
||||
|
||||
// Write the processed frame to file for visual inspection.
|
||||
std::ostringstream filename2;
|
||||
filename2 << webrtc::test::OutputPath() << "Resampler_"<< mode << "_" <<
|
||||
"from_" << target_width << "x" << target_height << "_to_" <<
|
||||
source_width << "x" << source_height << "_30Hz_P420.yuv";
|
||||
std::cout << "Watch " << filename2.str() << " and verify that it is okay."
|
||||
<< std::endl;
|
||||
stand_alone_file = fopen(filename2.str().c_str(), "wb");
|
||||
if (fwrite(out_frame->Buffer(), 1,
|
||||
out_frame->Length(), stand_alone_file) != out_frame->Length()) {
|
||||
fprintf(stderr, "Failed to write frame for scaling to width/height "
|
||||
"%d %d \n", source_width, source_height);
|
||||
return;
|
||||
}
|
||||
fclose(stand_alone_file);
|
||||
|
||||
// Compute the PSNR and check expectation.
|
||||
double psnr = I420PSNR(source_frame.Buffer(), out_frame->Buffer(),
|
||||
source_width, source_height);
|
||||
EXPECT_GT(psnr, expected_psnr);
|
||||
printf("PSNR: %f. PSNR is between source of size %d %d, and a modified "
|
||||
"source which is scaled down/up to: %d %d, and back to source size \n",
|
||||
psnr, source_width, source_height, target_width, target_height);
|
||||
|
||||
resampled_source_frame.Free();
|
||||
}
|
||||
fclose(standAloneFile);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
Loading…
x
Reference in New Issue
Block a user