A step forward toward switching WebRtc to the new VideoFrame.

Review URL: https://webrtc-codereview.appspot.com/818005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2820 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mikhal@webrtc.org 2012-09-24 21:09:54 +00:00
parent 0e6f597eb0
commit 2f4ff89a90
5 changed files with 56 additions and 61 deletions

View File

@ -16,6 +16,7 @@
#define WEBRTC_COMMON_VIDEO_LIBYUV_INCLUDE_WEBRTC_LIBYUV_H_
#include "common_types.h" // RawVideoTypes.
#include "modules/interface/module_common_types.h" // VideoFrame
#include "typedefs.h"
namespace webrtc {
@ -76,13 +77,12 @@ int CalcBufferSize(VideoType type, int width, int height);
// - 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.
// - src_width : src width in pixels.
// - src_height : src 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.
// - dst_frame : Reference to a destination frame.
// Return value: 0 if OK, < 0 otherwise.
int ConvertToI420(VideoType src_video_type,
@ -90,9 +90,8 @@ int ConvertToI420(VideoType src_video_type,
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);
VideoFrame* dst_frame);
// Convert From I420
// Input:

View File

@ -13,6 +13,7 @@
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "gtest/gtest.h"
#include "modules/interface/module_common_types.h" // VideoFrame
#include "system_wrappers/interface/tick_util.h"
#include "testsupport/fileutils.h"
@ -118,20 +119,21 @@ 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_];
VideoFrame res_i420_frame;
res_i420_frame.VerifyAndAllocate(frame_length_);
res_i420_frame.SetHeight(height_);
res_i420_frame.SetWidth(width_);
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));
0, kRotateNone, &res_i420_frame));
if (fwrite(res_i420_buffer, 1, frame_length_,
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
output_file) != static_cast<unsigned int>(frame_length_)) {
return;
}
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
psnr = I420PSNR(orig_buffer, res_i420_frame.Buffer(), width_, height_);
// Optimization Speed- quality trade-off => 45 dB only (platform dependant).
EXPECT_GT(ceil(psnr), 44);
j++;
@ -142,10 +144,10 @@ TEST_F(TestLibYuv, ConvertTest) {
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_);
0, kRotateNone, &res_i420_frame));
psnr = I420PSNR(orig_buffer, res_i420_frame.Buffer(), width_, height_);
EXPECT_EQ(48.0, psnr);
if (fwrite(res_i420_buffer, 1, frame_length_,
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
output_file) != static_cast<unsigned int>(frame_length_)) {
return;
}
@ -154,17 +156,16 @@ TEST_F(TestLibYuv, ConvertTest) {
delete [] out_uyvy_buffer;
// printf("\nConvert #%d I420 <-> I420 \n", j);
uint8_t* out_i420_buffer = new uint8_t[width_ * height_ * 3 / 2 ];
uint8_t* out_i420_buffer = new uint8_t[width_ * height_ * 3 / 2 ];
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));
if (fwrite(res_i420_buffer, 1, frame_length_,
0, kRotateNone, &res_i420_frame));
EXPECT_EQ(0, ConvertFromI420(res_i420_frame.Buffer(), width_, kI420, 0,
width_, height_, out_i420_buffer));
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
output_file) != static_cast<unsigned int>(frame_length_)) {
return;
}
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
psnr = I420PSNR(orig_buffer, out_i420_buffer, width_, height_);
EXPECT_EQ(48.0, psnr);
j++;
delete [] out_i420_buffer;
@ -177,13 +178,13 @@ TEST_F(TestLibYuv, ConvertTest) {
EXPECT_EQ(0, ConvertFromYV12(outYV120Buffer, width_,
kI420, 0,
width_, height_,
res_i420_buffer));
if (fwrite(res_i420_buffer, 1, frame_length_,
res_i420_frame.Buffer()));
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
output_file) != static_cast<unsigned int>(frame_length_)) {
return;
}
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
psnr = I420PSNR(orig_buffer, res_i420_frame.Buffer(), width_, height_);
EXPECT_EQ(48.0, psnr);
j++;
delete [] outYV120Buffer;
@ -194,14 +195,13 @@ TEST_F(TestLibYuv, ConvertTest) {
kYUY2, 0, width_, height_, out_yuy2_buffer));
EXPECT_EQ(0, ConvertToI420(kYUY2, out_yuy2_buffer, 0, 0, width_, height_,
0, width_, height_, width_,
kRotateNone, res_i420_buffer));
0, kRotateNone, &res_i420_frame));
if (fwrite(res_i420_buffer, 1, frame_length_,
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
output_file) != static_cast<unsigned int>(frame_length_)) {
return;
}
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
psnr = I420PSNR(orig_buffer, res_i420_frame.Buffer(), width_, height_);
EXPECT_EQ(48.0, psnr);
// printf("\nConvert #%d I420 <-> RGB565\n", j);
@ -210,14 +210,13 @@ TEST_F(TestLibYuv, ConvertTest) {
kRGB565, 0, width_, height_, out_rgb565_buffer));
EXPECT_EQ(0, ConvertToI420(kRGB565, out_rgb565_buffer, 0, 0, width_, height_,
0, width_, height_, width_,
kRotateNone, res_i420_buffer));
0, kRotateNone, &res_i420_frame));
if (fwrite(res_i420_buffer, 1, frame_length_,
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
output_file) != static_cast<unsigned int>(frame_length_)) {
return;
}
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
psnr = I420PSNR(orig_buffer, res_i420_frame.Buffer(), width_, height_);
// TODO(leozwang) Investigate the right psnr should be set for I420ToRGB565,
// Another example is I420ToRGB24, the psnr is 44
EXPECT_GT(ceil(psnr), 40);
@ -228,23 +227,22 @@ TEST_F(TestLibYuv, ConvertTest) {
kARGB, 0, width_, height_, out_argb8888_buffer));
EXPECT_EQ(0, ConvertToI420(kARGB, out_argb8888_buffer, 0, 0, width_, height_,
0, width_, height_, width_,
kRotateNone, res_i420_buffer));
0, kRotateNone, &res_i420_frame));
if (fwrite(res_i420_buffer, 1, frame_length_,
if (fwrite(res_i420_frame.Buffer(), 1, frame_length_,
output_file) != static_cast<unsigned int>(frame_length_)) {
return;
}
psnr = I420PSNR(orig_buffer, res_i420_buffer, width_, height_);
psnr = I420PSNR(orig_buffer, res_i420_frame.Buffer(), width_, height_);
// TODO(leozwang) Investigate the right psnr should be set for I420ToARGB8888,
EXPECT_GT(ceil(psnr), 42);
ASSERT_EQ(0, fclose(output_file));
res_i420_frame.Free();
delete [] out_argb8888_buffer;
delete [] out_rgb565_buffer;
delete [] out_yuy2_buffer;
delete [] res_i420_buffer;
delete [] orig_buffer;
}

View File

@ -170,15 +170,17 @@ int ConvertToI420(VideoType src_video_type,
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) {
VideoFrame* dst_frame) {
// All sanity tests are conducted within LibYuv.
int abs_dst_height = (dst_height < 0) ? -dst_height : dst_height;
int dst_height = dst_frame->Height();
int dst_width = dst_frame->Width();
// TODO(mikhal): When available, use actual stride value.
int dst_stride = dst_frame->Width();
int half_dst_width = (dst_width + 1) >> 1;
int half_dst_height = (abs_dst_height + 1) >> 1;
uint8_t* dst_yplane = dst_frame;
uint8_t* dst_uplane = dst_yplane + dst_width * abs_dst_height;
int half_dst_height = (dst_height + 1) >> 1;
uint8_t* dst_yplane = dst_frame->Buffer();
uint8_t* dst_uplane = dst_yplane + dst_width * dst_height;
uint8_t* dst_vplane = dst_uplane + half_dst_width * half_dst_height;
return libyuv::ConvertToI420(src_frame, sample_size,
dst_yplane, dst_stride,

View File

@ -208,8 +208,7 @@ WebRtc_Word32 VideoCaptureImpl::CaptureDelay()
}
WebRtc_Word32 VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame,
WebRtc_Word32 width, WebRtc_Word32 height, WebRtc_Word64 capture_time,
VideoCodecType codec_type) {
WebRtc_Word64 capture_time, VideoCodecType codec_type) {
UpdateFrameCount();// frame count used for local frame rate callback.
_startImageFrameIntervall = 0; // prevent the start image to be displayed.
@ -233,9 +232,6 @@ WebRtc_Word32 VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame,
}
last_capture_time_ = captureFrame.RenderTimeMs();
captureFrame.SetHeight(height);
captureFrame.SetWidth(width);
if (_dataCallBack) {
if (callOnCaptureDelayChanged) {
_dataCallBack->OnCaptureDelayChanged(_id, _captureDelay);
@ -289,16 +285,19 @@ WebRtc_Word32 VideoCaptureImpl::IncomingFrame(
}
memset(_captureFrame.Buffer(), 0, _captureFrame.Size());
// Keeping stride = width for I420 destination.
int dstStride = width;
_captureFrame.SetWidth(width);
// Setting absolute height (in case it was negative).
// In Windows, the image starts bottom left, instead of top left.
// Setting a negative source height, inverts the image (within LibYuv).
_captureFrame.SetHeight(abs(height));
// TODO(mikhal) : Set stride when available.
const int conversionResult = ConvertToI420(commonVideoType,
videoFrame,
0, 0, // No cropping
width, height,
videoFrameLength,
width, height, dstStride,
_rotateFrame,
_captureFrame.Buffer());
&_captureFrame);
if (conversionResult < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
@ -317,8 +316,7 @@ WebRtc_Word32 VideoCaptureImpl::IncomingFrame(
}
}
DeliverCapturedFrame(_captureFrame, width, abs(height), captureTime,
frameInfo.codecType);
DeliverCapturedFrame(_captureFrame, captureTime, frameInfo.codecType);
const WebRtc_UWord32 processTime =
@ -380,12 +378,10 @@ WebRtc_Word32 VideoCaptureImpl::IncomingFrameI420(
v_plane += video_frame.v_pitch;
}
_captureFrame.SetLength(frame_size);
_captureFrame.SetWidth(video_frame.width);
_captureFrame.SetHeight(video_frame.height);
DeliverCapturedFrame(_captureFrame,
video_frame.width,
video_frame.height,
captureTime,
kVideoCodecUnknown);
DeliverCapturedFrame(_captureFrame, captureTime, kVideoCodecUnknown);
return 0;
}

View File

@ -102,7 +102,7 @@ protected:
VideoCaptureImpl(const WebRtc_Word32 id);
virtual ~VideoCaptureImpl();
WebRtc_Word32 DeliverCapturedFrame(
VideoFrame& captureFrame, WebRtc_Word32 width, WebRtc_Word32 height,
VideoFrame& captureFrame,
WebRtc_Word64 capture_time, VideoCodecType codec_type);
WebRtc_Word32 _id; // Module ID