libyuv: Updating API to use latest ConvertFrom/To functionality
Review URL: http://webrtc-codereview.appspot.com/333020 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1302 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
e58112adec
commit
e2642494e4
@ -29,6 +29,7 @@ enum VideoType {
|
||||
kI420,
|
||||
kIYUV,
|
||||
kRGB24,
|
||||
kABGR,
|
||||
kARGB,
|
||||
kARGB4444,
|
||||
kRGB565,
|
||||
@ -39,9 +40,9 @@ enum VideoType {
|
||||
kMJPG,
|
||||
kNV21,
|
||||
kNV12,
|
||||
kARGBMac,
|
||||
kRGBAMac,
|
||||
kNumberOfVideoTypes
|
||||
kBGRA,
|
||||
kARGBMac, // TODO (mikhal): remove
|
||||
kRGBAMac, // TODO (mikhal): remove
|
||||
};
|
||||
|
||||
// Conversion between the RawVideoType and the LibYuv videoType.
|
||||
@ -105,6 +106,32 @@ int ConvertToI420(VideoType src_video_type,
|
||||
bool interlaced,
|
||||
VideoRotationMode rotate);
|
||||
|
||||
// The previous function will soon be removed.
|
||||
// TODO(mikhal): Remove legacy function after integration.
|
||||
|
||||
// Convert From/To I420
|
||||
// Input:
|
||||
// - src_video_type : Type of input video.
|
||||
// - src_frame : Pointer to a source frame.
|
||||
// - crop_x/crop_y : Starting positions for cropping (0 for no crop).
|
||||
// - src/dst_width : src/dst width in pixels.
|
||||
// - src/dst_height : src/dst height in pixels.
|
||||
// - sample_size : Required only for the parsing of MJPG (set to 0 else).
|
||||
// - dst_stride : Number of bytes in a row of the dst Y plane.
|
||||
// - rotate : Rotation mode of output image.
|
||||
// Output:
|
||||
// - dst_frame : Pointer to a destination frame.
|
||||
// Return value: 0 if OK, < 0 otherwise.
|
||||
|
||||
int ConvertToI420(VideoType src_video_type,
|
||||
const uint8_t* src_frame,
|
||||
int crop_x, int crop_y,
|
||||
int src_width, int src_height,
|
||||
int sample_size,
|
||||
int dst_width, int dst_height, int dst_stride,
|
||||
VideoRotationMode rotation,
|
||||
uint8_t* dst_frame);
|
||||
|
||||
// TODO(andrew): return to the int width and height types. This was swapped
|
||||
// temporarily to satisfy a linking error with the libjingle revision we and
|
||||
// Chrome pull, due to the removed vplib.
|
||||
@ -117,6 +144,29 @@ int ConvertFromI420(VideoType dst_video_type,
|
||||
uint8_t* dst_frame,
|
||||
bool interlaced,
|
||||
VideoRotationMode rotate);
|
||||
// The previous function will soon be removed.
|
||||
// TODO(mikhal): Remove legacy function after integration.
|
||||
// Input:
|
||||
// - src_frame : Pointer to a source frame.
|
||||
// - src_stride : Number of bytes in a row of the src Y plane.
|
||||
// - dst_video_type : Type of output video.
|
||||
// - dst_sample_size : Required only for the parsing of MJPG.
|
||||
// - width : Width in pixels.
|
||||
// - height : Height in pixels.
|
||||
// - dst_frame : Pointer to a source frame.
|
||||
|
||||
// - dst_frame : Pointer to a destination frame.
|
||||
// Return value: 0 if OK, < 0 otherwise.
|
||||
int ConvertFromI420(const uint8_t* src_frame, int src_stride,
|
||||
VideoType dst_video_type, int dst_sample_size,
|
||||
int width, int height,
|
||||
uint8_t* dst_frame);
|
||||
// ConvertFrom YV12.
|
||||
// Interface - same as above.
|
||||
int ConvertFromYV12(const uint8_t* src_frame, int src_stride,
|
||||
VideoType dst_video_type, int dst_sample_size,
|
||||
int width, int height,
|
||||
uint8_t* dst_frame);
|
||||
|
||||
// The following list describes the designated conversion function which
|
||||
// are called by the two prior general conversion function.
|
||||
|
@ -208,9 +208,10 @@ int ConvertI420ToARGB4444(const uint8_t* src_frame,
|
||||
int ConvertI420ToRGB565(const uint8_t* src_frame,
|
||||
uint8_t* dst_frame,
|
||||
int width, int height) {
|
||||
int abs_height = (height < 0) ? -height : height;
|
||||
const uint8_t* yplane = src_frame;
|
||||
const uint8_t* uplane = src_frame + width * height;
|
||||
const uint8_t* vplane = uplane + (width * height / 4);
|
||||
const uint8_t* uplane = src_frame + width * abs_height;
|
||||
const uint8_t* vplane = uplane + (width * abs_height / 4);
|
||||
|
||||
return libyuv::I420ToRGB565(yplane, width,
|
||||
uplane, width / 2,
|
||||
@ -221,6 +222,7 @@ int ConvertI420ToRGB565(const uint8_t* src_frame,
|
||||
|
||||
|
||||
// Same as ConvertI420ToRGB565 with a vertical flip.
|
||||
// TODO (mikhal): Deprecate
|
||||
int ConvertI420ToRGB565Android(const uint8_t* src_frame,
|
||||
uint8_t* dst_frame,
|
||||
int width, int height) {
|
||||
@ -571,12 +573,11 @@ int ConvertRGB24ToI420(int width, int height,
|
||||
uint8_t* yplane = dst_frame;
|
||||
uint8_t* uplane = yplane + width * height;
|
||||
uint8_t* vplane = uplane + (width * height / 4);
|
||||
// WebRtc expects a vertical flipped image.
|
||||
return libyuv::RGB24ToI420(src_frame, width * 3,
|
||||
yplane, width,
|
||||
uplane, width / 2,
|
||||
vplane, width / 2,
|
||||
width, -height);
|
||||
width, height);
|
||||
}
|
||||
|
||||
int ConvertI420ToARGBMac(const uint8_t* src_frame, uint8_t* dst_frame,
|
||||
@ -612,6 +613,131 @@ int ConvertARGBMacToI420(int width, int height,
|
||||
width, height);
|
||||
}
|
||||
|
||||
libyuv::RotationMode ConvertRotationMode(VideoRotationMode rotation) {
|
||||
switch(rotation) {
|
||||
case kRotateNone:
|
||||
return libyuv::kRotate0;
|
||||
break;
|
||||
case kRotate90:
|
||||
return libyuv::kRotate90;
|
||||
break;
|
||||
case kRotate180:
|
||||
return libyuv::kRotate180;
|
||||
break;
|
||||
case kRotate270:
|
||||
return libyuv::kRotate270;
|
||||
break;
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
int ConvertVideoType(VideoType video_type) {
|
||||
switch(video_type) {
|
||||
case kUnknown:
|
||||
return libyuv::FOURCC_ANY;
|
||||
break;
|
||||
case kI420:
|
||||
return libyuv::FOURCC_I420;
|
||||
break;
|
||||
case kIYUV: // same as KYV12
|
||||
case kYV12:
|
||||
return libyuv::FOURCC_YV12;
|
||||
break;
|
||||
case kRGB24:
|
||||
return libyuv::FOURCC_24BG;
|
||||
break;
|
||||
case kABGR:
|
||||
return libyuv::FOURCC_ABGR;
|
||||
break;
|
||||
case kARGB4444:
|
||||
case kRGB565:
|
||||
case kARGB1555:
|
||||
case kARGBMac:
|
||||
case kRGBAMac:
|
||||
// TODO(mikhal): Not supported;
|
||||
assert(false);
|
||||
return libyuv::FOURCC_ANY;
|
||||
break;
|
||||
case kYUY2:
|
||||
return libyuv::FOURCC_YUY2;
|
||||
break;
|
||||
case kUYVY:
|
||||
return libyuv::FOURCC_UYVY;
|
||||
break;
|
||||
case kMJPG:
|
||||
return libyuv::FOURCC_MJPG;
|
||||
break;
|
||||
case kNV21:
|
||||
return libyuv::FOURCC_NV21;
|
||||
break;
|
||||
case kNV12:
|
||||
return libyuv::FOURCC_NV12;
|
||||
break;
|
||||
case kARGB:
|
||||
return libyuv::FOURCC_ARGB;
|
||||
break;
|
||||
case kBGRA:
|
||||
return libyuv::FOURCC_BGRA;
|
||||
break;
|
||||
}
|
||||
// default value
|
||||
return libyuv::FOURCC_ANY;
|
||||
}
|
||||
|
||||
int ConvertToI420(VideoType src_video_type,
|
||||
const uint8_t* src_frame,
|
||||
int crop_x, int crop_y,
|
||||
int src_width, int src_height,
|
||||
int sample_size,
|
||||
int dst_width, int dst_height, int dst_stride,
|
||||
VideoRotationMode rotation,
|
||||
uint8_t* dst_frame) {
|
||||
// All sanity tests are conducted within LibYuv.
|
||||
uint8_t* dst_yplane = dst_frame;
|
||||
uint8_t* dst_uplane = dst_yplane + dst_width * dst_height;
|
||||
uint8_t* dst_vplane = dst_uplane + (dst_width * dst_height / 4);
|
||||
return libyuv::ConvertToI420(src_frame, sample_size,
|
||||
dst_yplane, dst_stride,
|
||||
dst_uplane, (dst_stride + 1) / 2,
|
||||
dst_vplane, (dst_stride + 1) / 2,
|
||||
crop_x, crop_y,
|
||||
src_width, src_height,
|
||||
dst_width, dst_height,
|
||||
ConvertRotationMode(rotation),
|
||||
ConvertVideoType(src_video_type));
|
||||
}
|
||||
|
||||
int ConvertFromI420(const uint8_t* src_frame, int src_stride,
|
||||
VideoType dst_video_type, int dst_sample_size,
|
||||
int width, int height,
|
||||
uint8_t* dst_frame) {
|
||||
const uint8_t* src_yplane = src_frame;
|
||||
const uint8_t* src_uplane = src_yplane + width * height;
|
||||
const uint8_t* src_vplane = src_uplane + (width * height / 4);
|
||||
return libyuv::ConvertFromI420(src_yplane, src_stride,
|
||||
src_uplane, (src_stride + 1) / 2,
|
||||
src_vplane, (src_stride + 1) / 2,
|
||||
dst_frame, dst_sample_size,
|
||||
width, height,
|
||||
ConvertVideoType(dst_video_type));
|
||||
}
|
||||
|
||||
int ConvertFromYV12(const uint8_t* src_frame, int src_stride,
|
||||
VideoType dst_video_type, int dst_sample_size,
|
||||
int width, int height,
|
||||
uint8_t* dst_frame) {
|
||||
const uint8_t* src_yplane = src_frame;
|
||||
const uint8_t* src_uplane = src_yplane + width * height;
|
||||
const uint8_t* src_vplane = src_uplane + (width * height / 4);
|
||||
// YV12 = Y, V, U
|
||||
return libyuv::ConvertFromI420(src_yplane, src_stride,
|
||||
src_vplane, (src_stride + 1) / 2,
|
||||
src_uplane, (src_stride + 1) / 2,
|
||||
dst_frame, dst_sample_size,
|
||||
width, height,
|
||||
ConvertVideoType(dst_video_type));
|
||||
}
|
||||
|
||||
int ConvertToI420(VideoType src_video_type,
|
||||
const uint8_t* src_frame,
|
||||
int width,
|
||||
@ -974,7 +1100,6 @@ double I420SSIM(const uint8_t* ref_frame,
|
||||
src_u_b, stride_uv,
|
||||
src_v_b, stride_uv,
|
||||
width, height);
|
||||
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -119,27 +119,27 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
// printf("\nConvert #%d I420 <-> RGB24\n", j);
|
||||
uint8_t* res_rgb_buffer2 = new uint8_t[width_ * height_ * 3];
|
||||
uint8_t* res_i420_buffer = new uint8_t[frame_length_];
|
||||
EXPECT_EQ(0, ConvertFromI420(kRGB24, orig_buffer, width_, height_,
|
||||
res_rgb_buffer2, false, kRotateNone));
|
||||
EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2, width_, height_,
|
||||
res_i420_buffer, false, kRotateNone));
|
||||
|
||||
EXPECT_EQ(0, ConvertFromI420(orig_buffer, width_, kRGB24, 0,
|
||||
width_, height_, res_rgb_buffer2));
|
||||
|
||||
EXPECT_EQ(0, ConvertToI420(kRGB24, res_rgb_buffer2, 0, 0, width_, height_,
|
||||
0, width_, height_, width_, kRotateNone,
|
||||
res_i420_buffer));
|
||||
|
||||
fwrite(res_i420_buffer, frame_length_, 1, output_file);
|
||||
//ImagePSNRfromBuffer(orig_buffer, res_i420_buffer, width_, height_, &psnr);
|
||||
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
|
||||
// Optimization Speed- quality trade-off => 45 dB only.
|
||||
// Optimization Speed- quality trade-off => 45 dB only (platform dependant).
|
||||
EXPECT_GT(ceil(psnr), 45);
|
||||
j++;
|
||||
delete [] res_rgb_buffer2;
|
||||
|
||||
// printf("\nConvert #%d I420 <-> UYVY\n", j);
|
||||
uint8_t* out_uyvy_buffer = new uint8_t[width_ * height_ * 2];
|
||||
EXPECT_EQ(0, ConvertFromI420(kUYVY, orig_buffer, width_,
|
||||
height_, out_uyvy_buffer, false, kRotateNone));
|
||||
|
||||
EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer, width_, height_,
|
||||
res_i420_buffer, false, kRotateNone));
|
||||
//ImagePSNRfromBuffer(orig_buffer, res_i420_buffer, width_, height_, &psnr);
|
||||
EXPECT_EQ(0, ConvertFromI420(orig_buffer, width_,
|
||||
kUYVY, 0, width_, height_, out_uyvy_buffer));
|
||||
EXPECT_EQ(0, ConvertToI420(kUYVY, out_uyvy_buffer, 0, 0, width_, height_,
|
||||
0, width_, height_, width_,kRotateNone, res_i420_buffer));
|
||||
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
|
||||
EXPECT_EQ(48.0, psnr);
|
||||
fwrite(res_i420_buffer, frame_length_, 1, output_file);
|
||||
@ -149,12 +149,12 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
|
||||
// printf("\nConvert #%d I420 <-> I420 \n", j);
|
||||
uint8_t* out_i420_buffer = new uint8_t[width_ * height_ * 3 / 2 ];
|
||||
EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, width_, height_,
|
||||
out_i420_buffer, false, kRotateNone));
|
||||
EXPECT_EQ(0, ConvertFromI420(kI420 , out_i420_buffer, width_, height_,
|
||||
res_i420_buffer, false, kRotateNone));
|
||||
EXPECT_EQ(0, ConvertToI420(kI420, orig_buffer, 0, 0, width_, height_,
|
||||
0, width_, height_, width_,
|
||||
kRotateNone, out_i420_buffer));
|
||||
EXPECT_EQ(0, ConvertFromI420(out_i420_buffer, width_, kI420, 0,
|
||||
width_, height_, res_i420_buffer));
|
||||
fwrite(res_i420_buffer, frame_length_, 1, output_file);
|
||||
//ImagePSNRfromBuffer(orig_buffer, res_i420_buffer, width_, height_, &psnr);
|
||||
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
|
||||
EXPECT_EQ(48.0, psnr);
|
||||
j++;
|
||||
@ -163,13 +163,14 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
// printf("\nConvert #%d I420 <-> YV12\n", j);
|
||||
uint8_t* outYV120Buffer = new uint8_t[frame_length_];
|
||||
|
||||
EXPECT_EQ(0, ConvertFromI420(kYV12, orig_buffer, width_, height_,
|
||||
outYV120Buffer, false, kRotateNone));
|
||||
EXPECT_EQ(0, ConvertYV12ToI420(outYV120Buffer, width_, height_,
|
||||
EXPECT_EQ(0, ConvertFromI420(orig_buffer, width_, kYV12, 0,
|
||||
width_, height_, outYV120Buffer));
|
||||
EXPECT_EQ(0, ConvertFromYV12(outYV120Buffer, width_,
|
||||
kI420, 0,
|
||||
width_, height_,
|
||||
res_i420_buffer));
|
||||
fwrite(res_i420_buffer, frame_length_, 1, output_file);
|
||||
|
||||
//ImagePSNRfromBuffer(orig_buffer, res_i420_buffer, width_, height_, &psnr);
|
||||
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
|
||||
EXPECT_EQ(48.0, psnr);
|
||||
j++;
|
||||
@ -177,14 +178,14 @@ TEST_F(TestLibYuv, ConvertTest) {
|
||||
|
||||
// printf("\nConvert #%d I420 <-> YUY2\n", j);
|
||||
uint8_t* out_yuy2_buffer = new uint8_t[width_ * height_ * 2];
|
||||
EXPECT_EQ(0, ConvertFromI420(orig_buffer, width_,
|
||||
kYUY2, 0, width_, height_, out_yuy2_buffer));
|
||||
|
||||
EXPECT_EQ(0, ConvertFromI420(kYUY2, orig_buffer, width_, height_,
|
||||
out_yuy2_buffer, false, kRotateNone));
|
||||
EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer, width_, height_,
|
||||
res_i420_buffer, false, kRotateNone));
|
||||
EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer, 0, 0, width_, height_,
|
||||
0, width_, height_, width_,
|
||||
kRotateNone, res_i420_buffer));
|
||||
|
||||
fwrite(res_i420_buffer, frame_length_, 1, output_file);
|
||||
//ImagePSNRfromBuffer(orig_buffer, res_i420_buffer, width_, height_, &psnr);
|
||||
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
|
||||
EXPECT_EQ(48.0, psnr);
|
||||
delete [] out_yuy2_buffer;
|
||||
|
Loading…
Reference in New Issue
Block a user