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:
parent
0e6f597eb0
commit
2f4ff89a90
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user