Revert of Make cricket::VideoFrame inherit webrtc::VideoFrame. (patchset #9 id:160001 of https://codereview.webrtc.org/2315663002/ )
Reason for revert: Breaks compile for Chromium builds: https://build.chromium.org/p/chromium.webrtc.fyi/builders/Linux%20Builder/builds/10761 https://build.chromium.org/p/chromium.webrtc.fyi/builders/Mac%20Builder/builds/18142 FAILED: obj/remoting/protocol/protocol/webrtc_video_renderer_adapter.o ../../remoting/protocol/webrtc_video_renderer_adapter.cc:110:52: error: no member named 'transport_frame_id' in 'cricket::VideoFrame' weak_factory_.GetWeakPtr(), frame.transport_frame_id(), ~~~~~ ^ 1 error generated. Please run chromium trybots as described at https://webrtc.org/contributing/#tryjobs-on-chromium-trybots before relanding. Original issue's description: > Make cricket::VideoFrame inherit webrtc::VideoFrame. Delete > all methods but a few constructors. And similarly for the > subclass cricket::WebRtcVideoFrame. > > TBR=tkchin@webrtc.org # Added an include line > BUG=webrtc:5682 > > Committed: https://crrev.com/dda6ec008a0fc8d52e118814fb779032e8931968 > Cr-Commit-Position: refs/heads/master@{#14576} TBR=perkj@webrtc.org,pthatcher@webrtc.org,pthatcher@chromium.org,tkchin@webrtc.org,nisse@webrtc.org NOTRY=True NOPRESUBMIT=True BUG=webrtc:5682 Review-Url: https://codereview.webrtc.org/2402853002 Cr-Commit-Position: refs/heads/master@{#14583}
This commit is contained in:
@ -81,6 +81,7 @@ rtc_static_library("rtc_media") {
|
|||||||
"base/videocapturerfactory.h",
|
"base/videocapturerfactory.h",
|
||||||
"base/videocommon.cc",
|
"base/videocommon.cc",
|
||||||
"base/videocommon.h",
|
"base/videocommon.h",
|
||||||
|
"base/videoframe.cc",
|
||||||
"base/videoframe.h",
|
"base/videoframe.h",
|
||||||
"base/videosourcebase.cc",
|
"base/videosourcebase.cc",
|
||||||
"base/videosourcebase.h",
|
"base/videosourcebase.h",
|
||||||
@ -101,6 +102,7 @@ rtc_static_library("rtc_media") {
|
|||||||
"engine/webrtcvideoencoderfactory.h",
|
"engine/webrtcvideoencoderfactory.h",
|
||||||
"engine/webrtcvideoengine2.cc",
|
"engine/webrtcvideoengine2.cc",
|
||||||
"engine/webrtcvideoengine2.h",
|
"engine/webrtcvideoengine2.h",
|
||||||
|
"engine/webrtcvideoframe.cc",
|
||||||
"engine/webrtcvideoframe.h",
|
"engine/webrtcvideoframe.h",
|
||||||
"engine/webrtcvoe.h",
|
"engine/webrtcvoe.h",
|
||||||
"engine/webrtcvoiceengine.cc",
|
"engine/webrtcvoiceengine.cc",
|
||||||
@ -304,12 +306,14 @@ if (rtc_include_tests) {
|
|||||||
"base/videocapturer_unittest.cc",
|
"base/videocapturer_unittest.cc",
|
||||||
"base/videocommon_unittest.cc",
|
"base/videocommon_unittest.cc",
|
||||||
"base/videoengine_unittest.h",
|
"base/videoengine_unittest.h",
|
||||||
|
"base/videoframe_unittest.h",
|
||||||
"engine/nullwebrtcvideoengine_unittest.cc",
|
"engine/nullwebrtcvideoengine_unittest.cc",
|
||||||
"engine/payload_type_mapper_unittest.cc",
|
"engine/payload_type_mapper_unittest.cc",
|
||||||
"engine/simulcast_unittest.cc",
|
"engine/simulcast_unittest.cc",
|
||||||
"engine/webrtcmediaengine_unittest.cc",
|
"engine/webrtcmediaengine_unittest.cc",
|
||||||
"engine/webrtcvideocapturer_unittest.cc",
|
"engine/webrtcvideocapturer_unittest.cc",
|
||||||
"engine/webrtcvideoengine2_unittest.cc",
|
"engine/webrtcvideoengine2_unittest.cc",
|
||||||
|
"engine/webrtcvideoframe_unittest.cc",
|
||||||
"engine/webrtcvoiceengine_unittest.cc",
|
"engine/webrtcvoiceengine_unittest.cc",
|
||||||
"sctp/sctpdataengine_unittest.cc",
|
"sctp/sctpdataengine_unittest.cc",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -13,7 +13,6 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/logging.h"
|
|
||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
|
|
||||||
@ -65,7 +64,7 @@ void VideoBroadcaster::OnFrame(const cricket::VideoFrame& frame) {
|
|||||||
if (sink_pair.wants.black_frames) {
|
if (sink_pair.wants.black_frames) {
|
||||||
sink_pair.sink->OnFrame(cricket::WebRtcVideoFrame(
|
sink_pair.sink->OnFrame(cricket::WebRtcVideoFrame(
|
||||||
GetBlackFrameBuffer(frame.width(), frame.height()), frame.rotation(),
|
GetBlackFrameBuffer(frame.width(), frame.height()), frame.rotation(),
|
||||||
frame.timestamp_us()));
|
frame.timestamp_us(), frame.transport_frame_id()));
|
||||||
} else {
|
} else {
|
||||||
sink_pair.sink->OnFrame(frame);
|
sink_pair.sink->OnFrame(frame);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -140,7 +140,7 @@ TEST(VideoBroadcasterTest, SinkWantsBlackFrames) {
|
|||||||
buffer->InitializeData();
|
buffer->InitializeData();
|
||||||
|
|
||||||
cricket::WebRtcVideoFrame frame1(buffer, webrtc::kVideoRotation_0,
|
cricket::WebRtcVideoFrame frame1(buffer, webrtc::kVideoRotation_0,
|
||||||
10 /* timestamp_us */);
|
10 /* timestamp_us */, 0 /* frame_id */);
|
||||||
broadcaster.OnFrame(frame1);
|
broadcaster.OnFrame(frame1);
|
||||||
EXPECT_TRUE(sink1.black_frame());
|
EXPECT_TRUE(sink1.black_frame());
|
||||||
EXPECT_EQ(10, sink1.timestamp_us());
|
EXPECT_EQ(10, sink1.timestamp_us());
|
||||||
@ -154,7 +154,7 @@ TEST(VideoBroadcasterTest, SinkWantsBlackFrames) {
|
|||||||
broadcaster.AddOrUpdateSink(&sink2, wants2);
|
broadcaster.AddOrUpdateSink(&sink2, wants2);
|
||||||
|
|
||||||
cricket::WebRtcVideoFrame frame2(buffer, webrtc::kVideoRotation_0,
|
cricket::WebRtcVideoFrame frame2(buffer, webrtc::kVideoRotation_0,
|
||||||
30 /* timestamp_us */);
|
30 /* timestamp_us */, 0 /* frame_id */);
|
||||||
broadcaster.OnFrame(frame2);
|
broadcaster.OnFrame(frame2);
|
||||||
EXPECT_FALSE(sink1.black_frame());
|
EXPECT_FALSE(sink1.black_frame());
|
||||||
EXPECT_EQ(30, sink1.timestamp_us());
|
EXPECT_EQ(30, sink1.timestamp_us());
|
||||||
|
|||||||
171
webrtc/media/base/videoframe.cc
Normal file
171
webrtc/media/base/videoframe.cc
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/media/base/videoframe.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "webrtc/base/arraysize.h"
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
|
#include "webrtc/base/logging.h"
|
||||||
|
#include "webrtc/media/base/videocommon.h"
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
|
||||||
|
static const size_t kMaxSampleSize = 1000000000u;
|
||||||
|
// Returns whether a sample is valid.
|
||||||
|
bool VideoFrame::Validate(uint32_t fourcc,
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
const uint8_t* sample,
|
||||||
|
size_t sample_size) {
|
||||||
|
if (h < 0) {
|
||||||
|
h = -h;
|
||||||
|
}
|
||||||
|
// 16384 is maximum resolution for VP8 codec.
|
||||||
|
if (w < 1 || w > 16384 || h < 1 || h > 16384) {
|
||||||
|
LOG(LS_ERROR) << "Invalid dimensions: " << w << "x" << h;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32_t format = CanonicalFourCC(fourcc);
|
||||||
|
int expected_bpp = 8;
|
||||||
|
switch (format) {
|
||||||
|
case FOURCC_I400:
|
||||||
|
case FOURCC_RGGB:
|
||||||
|
case FOURCC_BGGR:
|
||||||
|
case FOURCC_GRBG:
|
||||||
|
case FOURCC_GBRG:
|
||||||
|
expected_bpp = 8;
|
||||||
|
break;
|
||||||
|
case FOURCC_I420:
|
||||||
|
case FOURCC_I411:
|
||||||
|
case FOURCC_YU12:
|
||||||
|
case FOURCC_YV12:
|
||||||
|
case FOURCC_M420:
|
||||||
|
case FOURCC_NV21:
|
||||||
|
case FOURCC_NV12:
|
||||||
|
expected_bpp = 12;
|
||||||
|
break;
|
||||||
|
case FOURCC_I422:
|
||||||
|
case FOURCC_YV16:
|
||||||
|
case FOURCC_YUY2:
|
||||||
|
case FOURCC_UYVY:
|
||||||
|
case FOURCC_RGBP:
|
||||||
|
case FOURCC_RGBO:
|
||||||
|
case FOURCC_R444:
|
||||||
|
expected_bpp = 16;
|
||||||
|
break;
|
||||||
|
case FOURCC_I444:
|
||||||
|
case FOURCC_YV24:
|
||||||
|
case FOURCC_24BG:
|
||||||
|
case FOURCC_RAW:
|
||||||
|
expected_bpp = 24;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOURCC_ABGR:
|
||||||
|
case FOURCC_BGRA:
|
||||||
|
case FOURCC_ARGB:
|
||||||
|
expected_bpp = 32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOURCC_MJPG:
|
||||||
|
case FOURCC_H264:
|
||||||
|
expected_bpp = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expected_bpp = 8; // Expect format is at least 8 bits per pixel.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size_t expected_size = (w * expected_bpp + 7) / 8 * h;
|
||||||
|
// For compressed formats, expect 4 bits per 16 x 16 macro. I420 would be
|
||||||
|
// 6 bits, but grey can be 4 bits.
|
||||||
|
if (expected_bpp == 0) {
|
||||||
|
expected_size = ((w + 15) / 16) * ((h + 15) / 16) * 4 / 8;
|
||||||
|
}
|
||||||
|
if (sample == NULL) {
|
||||||
|
LOG(LS_ERROR) << "NULL sample pointer."
|
||||||
|
<< " format: " << GetFourccName(format)
|
||||||
|
<< " bpp: " << expected_bpp
|
||||||
|
<< " size: " << w << "x" << h
|
||||||
|
<< " expected: " << expected_size
|
||||||
|
<< " " << sample_size;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO(fbarchard): Make function to dump information about frames.
|
||||||
|
uint8_t four_samples[4] = {0, 0, 0, 0};
|
||||||
|
for (size_t i = 0; i < arraysize(four_samples) && i < sample_size; ++i) {
|
||||||
|
four_samples[i] = sample[i];
|
||||||
|
}
|
||||||
|
if (sample_size < expected_size) {
|
||||||
|
LOG(LS_ERROR) << "Size field is too small."
|
||||||
|
<< " format: " << GetFourccName(format)
|
||||||
|
<< " bpp: " << expected_bpp
|
||||||
|
<< " size: " << w << "x" << h
|
||||||
|
<< " " << sample_size
|
||||||
|
<< " expected: " << expected_size
|
||||||
|
<< " sample[0..3]: " << static_cast<int>(four_samples[0])
|
||||||
|
<< ", " << static_cast<int>(four_samples[1])
|
||||||
|
<< ", " << static_cast<int>(four_samples[2])
|
||||||
|
<< ", " << static_cast<int>(four_samples[3]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (sample_size > kMaxSampleSize) {
|
||||||
|
LOG(LS_WARNING) << "Size field is invalid."
|
||||||
|
<< " format: " << GetFourccName(format)
|
||||||
|
<< " bpp: " << expected_bpp
|
||||||
|
<< " size: " << w << "x" << h
|
||||||
|
<< " " << sample_size
|
||||||
|
<< " expected: " << 2 * expected_size
|
||||||
|
<< " sample[0..3]: " << static_cast<int>(four_samples[0])
|
||||||
|
<< ", " << static_cast<int>(four_samples[1])
|
||||||
|
<< ", " << static_cast<int>(four_samples[2])
|
||||||
|
<< ", " << static_cast<int>(four_samples[3]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Show large size warning once every 100 frames.
|
||||||
|
// TODO(fbarchard): Make frame counter atomic for thread safety.
|
||||||
|
static int large_warn100 = 0;
|
||||||
|
size_t large_expected_size = expected_size * 2;
|
||||||
|
if (expected_bpp >= 8 &&
|
||||||
|
(sample_size > large_expected_size || sample_size > kMaxSampleSize) &&
|
||||||
|
large_warn100 % 100 == 0) {
|
||||||
|
++large_warn100;
|
||||||
|
LOG(LS_WARNING) << "Size field is too large."
|
||||||
|
<< " format: " << GetFourccName(format)
|
||||||
|
<< " bpp: " << expected_bpp
|
||||||
|
<< " size: " << w << "x" << h
|
||||||
|
<< " bytes: " << sample_size
|
||||||
|
<< " expected: " << large_expected_size
|
||||||
|
<< " sample[0..3]: " << static_cast<int>(four_samples[0])
|
||||||
|
<< ", " << static_cast<int>(four_samples[1])
|
||||||
|
<< ", " << static_cast<int>(four_samples[2])
|
||||||
|
<< ", " << static_cast<int>(four_samples[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(fbarchard): Add duplicate pixel check.
|
||||||
|
// TODO(fbarchard): Use frame counter atomic for thread safety.
|
||||||
|
static bool valid_once = true;
|
||||||
|
if (valid_once) {
|
||||||
|
valid_once = false;
|
||||||
|
LOG(LS_INFO) << "Validate frame passed."
|
||||||
|
<< " format: " << GetFourccName(format)
|
||||||
|
<< " bpp: " << expected_bpp
|
||||||
|
<< " size: " << w << "x" << h
|
||||||
|
<< " bytes: " << sample_size
|
||||||
|
<< " expected: " << expected_size
|
||||||
|
<< " sample[0..3]: " << static_cast<int>(four_samples[0])
|
||||||
|
<< ", " << static_cast<int>(four_samples[1])
|
||||||
|
<< ", " << static_cast<int>(four_samples[2])
|
||||||
|
<< ", " << static_cast<int>(four_samples[3]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cricket
|
||||||
@ -8,24 +8,57 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO(nisse): Deprecated, replace cricket::VideoFrame with
|
|
||||||
// webrtc::VideoFrame everywhere, then delete this file. See
|
|
||||||
// https://bugs.chromium.org/p/webrtc/issues/detail?id=5682.
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MEDIA_BASE_VIDEOFRAME_H_
|
#ifndef WEBRTC_MEDIA_BASE_VIDEOFRAME_H_
|
||||||
#define WEBRTC_MEDIA_BASE_VIDEOFRAME_H_
|
#define WEBRTC_MEDIA_BASE_VIDEOFRAME_H_
|
||||||
|
|
||||||
#include "webrtc/video_frame.h"
|
#include "webrtc/base/basictypes.h"
|
||||||
|
#include "webrtc/base/stream.h"
|
||||||
|
#include "webrtc/common_video/include/video_frame_buffer.h"
|
||||||
|
#include "webrtc/common_video/rotation.h"
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
|
|
||||||
class VideoFrame : public webrtc::VideoFrame {
|
// Represents a YUV420 (a.k.a. I420) video frame.
|
||||||
protected:
|
|
||||||
VideoFrame() : webrtc::VideoFrame() {}
|
// TODO(nisse): This class duplicates webrtc::VideoFrame. There's
|
||||||
VideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
// ongoing work to merge the classes. See
|
||||||
webrtc::VideoRotation rotation,
|
// https://bugs.chromium.org/p/webrtc/issues/detail?id=5682.
|
||||||
int64_t timestamp_us)
|
class VideoFrame {
|
||||||
: webrtc::VideoFrame(buffer, rotation, timestamp_us) {}
|
public:
|
||||||
|
VideoFrame() {}
|
||||||
|
virtual ~VideoFrame() {}
|
||||||
|
|
||||||
|
// Basic accessors.
|
||||||
|
// Note this is the width and height without rotation applied.
|
||||||
|
virtual int width() const = 0;
|
||||||
|
virtual int height() const = 0;
|
||||||
|
|
||||||
|
// Returns the underlying video frame buffer. This function is ok to call
|
||||||
|
// multiple times, but the returned object will refer to the same memory.
|
||||||
|
virtual const rtc::scoped_refptr<webrtc::VideoFrameBuffer>&
|
||||||
|
video_frame_buffer() const = 0;
|
||||||
|
|
||||||
|
// Frame ID. Normally RTP timestamp when the frame was received using RTP.
|
||||||
|
virtual uint32_t transport_frame_id() const = 0;
|
||||||
|
|
||||||
|
// System monotonic clock, same timebase as rtc::TimeMicros().
|
||||||
|
virtual int64_t timestamp_us() const = 0;
|
||||||
|
virtual void set_timestamp_us(int64_t time_us) = 0;
|
||||||
|
|
||||||
|
// Indicates the rotation angle in degrees.
|
||||||
|
virtual webrtc::VideoRotation rotation() const = 0;
|
||||||
|
|
||||||
|
// Tests if sample is valid. Returns true if valid.
|
||||||
|
|
||||||
|
// TODO(nisse): Deprecated. Should be deleted in the cricket::VideoFrame and
|
||||||
|
// webrtc::VideoFrame merge. Validation of sample_size possibly moved to
|
||||||
|
// libyuv::ConvertToI420. As an initial step, demote this method to protected
|
||||||
|
// status. Used only by WebRtcVideoFrame::Reset.
|
||||||
|
static bool Validate(uint32_t fourcc,
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
const uint8_t* sample,
|
||||||
|
size_t sample_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
|||||||
1369
webrtc/media/base/videoframe_unittest.h
Normal file
1369
webrtc/media/base/videoframe_unittest.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -355,7 +355,7 @@ void WebRtcVideoCapturer::OnIncomingCapturedFrame(
|
|||||||
|
|
||||||
OnFrame(cricket::WebRtcVideoFrame(
|
OnFrame(cricket::WebRtcVideoFrame(
|
||||||
sample.video_frame_buffer(), sample.rotation(),
|
sample.video_frame_buffer(), sample.rotation(),
|
||||||
sample.render_time_ms() * rtc::kNumMicrosecsPerMillisec),
|
sample.render_time_ms() * rtc::kNumMicrosecsPerMillisec, 0),
|
||||||
sample.width(), sample.height());
|
sample.width(), sample.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2510,10 +2510,10 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::OnFrame(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sink_->OnFrame(
|
WebRtcVideoFrame render_frame(
|
||||||
WebRtcVideoFrame(frame.video_frame_buffer(), frame.rotation(),
|
frame.video_frame_buffer(), frame.rotation(),
|
||||||
frame.render_time_ms() * rtc::kNumNanosecsPerMicrosec,
|
frame.render_time_ms() * rtc::kNumNanosecsPerMicrosec, frame.timestamp());
|
||||||
frame.timestamp()));
|
sink_->OnFrame(render_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const {
|
bool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const {
|
||||||
|
|||||||
@ -26,11 +26,11 @@
|
|||||||
#include "webrtc/media/base/videosourceinterface.h"
|
#include "webrtc/media/base/videosourceinterface.h"
|
||||||
#include "webrtc/call.h"
|
#include "webrtc/call.h"
|
||||||
#include "webrtc/media/base/mediaengine.h"
|
#include "webrtc/media/base/mediaengine.h"
|
||||||
#include "webrtc/media/base/videoframe.h"
|
|
||||||
#include "webrtc/media/engine/webrtcvideochannelfactory.h"
|
#include "webrtc/media/engine/webrtcvideochannelfactory.h"
|
||||||
#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
|
#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
|
||||||
#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
|
#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
|
||||||
#include "webrtc/transport.h"
|
#include "webrtc/transport.h"
|
||||||
|
#include "webrtc/video_frame.h"
|
||||||
#include "webrtc/video_receive_stream.h"
|
#include "webrtc/video_receive_stream.h"
|
||||||
#include "webrtc/video_send_stream.h"
|
#include "webrtc/video_send_stream.h"
|
||||||
|
|
||||||
|
|||||||
154
webrtc/media/engine/webrtcvideoframe.cc
Normal file
154
webrtc/media/engine/webrtcvideoframe.cc
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/media/engine/webrtcvideoframe.h"
|
||||||
|
|
||||||
|
#include "libyuv/convert.h"
|
||||||
|
#include "webrtc/base/logging.h"
|
||||||
|
#include "webrtc/media/base/videocapturer.h"
|
||||||
|
#include "webrtc/media/base/videocommon.h"
|
||||||
|
#include "webrtc/video_frame.h"
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
|
||||||
|
WebRtcVideoFrame::WebRtcVideoFrame()
|
||||||
|
: timestamp_us_(0), rotation_(webrtc::kVideoRotation_0) {}
|
||||||
|
|
||||||
|
WebRtcVideoFrame::WebRtcVideoFrame(
|
||||||
|
const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
||||||
|
webrtc::VideoRotation rotation,
|
||||||
|
int64_t timestamp_us,
|
||||||
|
uint32_t transport_frame_id)
|
||||||
|
: video_frame_buffer_(buffer),
|
||||||
|
timestamp_us_(timestamp_us),
|
||||||
|
transport_frame_id_(transport_frame_id),
|
||||||
|
rotation_(rotation) {}
|
||||||
|
|
||||||
|
WebRtcVideoFrame::WebRtcVideoFrame(
|
||||||
|
const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
||||||
|
webrtc::VideoRotation rotation,
|
||||||
|
int64_t timestamp_us)
|
||||||
|
: WebRtcVideoFrame(buffer, rotation, timestamp_us, 0) {};
|
||||||
|
|
||||||
|
WebRtcVideoFrame::WebRtcVideoFrame(
|
||||||
|
const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
||||||
|
int64_t time_stamp_ns,
|
||||||
|
webrtc::VideoRotation rotation)
|
||||||
|
: WebRtcVideoFrame(buffer,
|
||||||
|
rotation,
|
||||||
|
time_stamp_ns / rtc::kNumNanosecsPerMicrosec,
|
||||||
|
0) {}
|
||||||
|
|
||||||
|
WebRtcVideoFrame::~WebRtcVideoFrame() {}
|
||||||
|
|
||||||
|
bool WebRtcVideoFrame::Init(uint32_t format,
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
int dw,
|
||||||
|
int dh,
|
||||||
|
uint8_t* sample,
|
||||||
|
size_t sample_size,
|
||||||
|
int64_t time_stamp_ns,
|
||||||
|
webrtc::VideoRotation rotation) {
|
||||||
|
return Reset(format, w, h, dw, dh, sample, sample_size,
|
||||||
|
time_stamp_ns / rtc::kNumNanosecsPerMicrosec, rotation,
|
||||||
|
true /*apply_rotation*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebRtcVideoFrame::width() const {
|
||||||
|
return video_frame_buffer_ ? video_frame_buffer_->width() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebRtcVideoFrame::height() const {
|
||||||
|
return video_frame_buffer_ ? video_frame_buffer_->height() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rtc::scoped_refptr<webrtc::VideoFrameBuffer>&
|
||||||
|
WebRtcVideoFrame::video_frame_buffer() const {
|
||||||
|
return video_frame_buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WebRtcVideoFrame::transport_frame_id() const {
|
||||||
|
return transport_frame_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t WebRtcVideoFrame::timestamp_us() const {
|
||||||
|
return timestamp_us_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcVideoFrame::set_timestamp_us(int64_t time_us) {
|
||||||
|
timestamp_us_ = time_us;
|
||||||
|
}
|
||||||
|
|
||||||
|
webrtc::VideoRotation WebRtcVideoFrame::rotation() const {
|
||||||
|
return rotation_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebRtcVideoFrame::Reset(uint32_t format,
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
int dw,
|
||||||
|
int dh,
|
||||||
|
uint8_t* sample,
|
||||||
|
size_t sample_size,
|
||||||
|
int64_t timestamp_us,
|
||||||
|
webrtc::VideoRotation rotation,
|
||||||
|
bool apply_rotation) {
|
||||||
|
if (!Validate(format, w, h, sample, sample_size)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Translate aliases to standard enums (e.g., IYUV -> I420).
|
||||||
|
format = CanonicalFourCC(format);
|
||||||
|
|
||||||
|
// Set up a new buffer.
|
||||||
|
// TODO(fbarchard): Support lazy allocation.
|
||||||
|
int new_width = dw;
|
||||||
|
int new_height = dh;
|
||||||
|
// If rotated swap width, height.
|
||||||
|
if (apply_rotation && (rotation == 90 || rotation == 270)) {
|
||||||
|
new_width = dh;
|
||||||
|
new_height = dw;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::scoped_refptr<webrtc::I420Buffer> buffer =
|
||||||
|
webrtc::I420Buffer::Create(new_width, new_height);
|
||||||
|
video_frame_buffer_ = buffer;
|
||||||
|
rotation_ = apply_rotation ? webrtc::kVideoRotation_0 : rotation;
|
||||||
|
|
||||||
|
int horiz_crop = ((w - dw) / 2) & ~1;
|
||||||
|
// ARGB on Windows has negative height.
|
||||||
|
// The sample's layout in memory is normal, so just correct crop.
|
||||||
|
int vert_crop = ((abs(h) - dh) / 2) & ~1;
|
||||||
|
// Conversion functions expect negative height to flip the image.
|
||||||
|
int idh = (h < 0) ? -dh : dh;
|
||||||
|
int r = libyuv::ConvertToI420(
|
||||||
|
sample, sample_size,
|
||||||
|
buffer->MutableDataY(), buffer->StrideY(),
|
||||||
|
buffer->MutableDataU(), buffer->StrideU(),
|
||||||
|
buffer->MutableDataV(), buffer->StrideV(),
|
||||||
|
horiz_crop, vert_crop, w, h, dw, idh,
|
||||||
|
static_cast<libyuv::RotationMode>(
|
||||||
|
apply_rotation ? rotation : webrtc::kVideoRotation_0),
|
||||||
|
format);
|
||||||
|
if (r) {
|
||||||
|
LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format)
|
||||||
|
<< " return code : " << r;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
timestamp_us_ = timestamp_us;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h) {
|
||||||
|
video_frame_buffer_ = webrtc::I420Buffer::Create(w, h);
|
||||||
|
rotation_ = webrtc::kVideoRotation_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cricket
|
||||||
@ -8,10 +8,6 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO(nisse): Deprecated, replace cricket::WebRtcVideoFrame with
|
|
||||||
// webrtc::VideoFrame everywhere, then delete this file. See
|
|
||||||
// https://bugs.chromium.org/p/webrtc/issues/detail?id=5682.
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOFRAME_H_
|
#ifndef WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOFRAME_H_
|
||||||
#define WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOFRAME_H_
|
#define WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOFRAME_H_
|
||||||
|
|
||||||
@ -26,22 +22,100 @@
|
|||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
|
|
||||||
|
// TODO(nisse): This class will be deleted when the cricket::VideoFrame and
|
||||||
|
// webrtc::VideoFrame classes are merged. See
|
||||||
|
// https://bugs.chromium.org/p/webrtc/issues/detail?id=5682. Try to use only the
|
||||||
|
// preferred constructor, and the non-deprecated methods of the VideoFrame base
|
||||||
|
// class.
|
||||||
class WebRtcVideoFrame : public VideoFrame {
|
class WebRtcVideoFrame : public VideoFrame {
|
||||||
public:
|
public:
|
||||||
WebRtcVideoFrame() : VideoFrame() {}
|
// TODO(nisse): Deprecated. Using the default constructor violates the
|
||||||
WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
// reasonable assumption that video_frame_buffer() returns a valid buffer.
|
||||||
webrtc::VideoRotation rotation,
|
WebRtcVideoFrame();
|
||||||
int64_t timestamp_us)
|
|
||||||
: VideoFrame(buffer, rotation, timestamp_us) {}
|
// Preferred constructor.
|
||||||
WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
||||||
webrtc::VideoRotation rotation,
|
webrtc::VideoRotation rotation,
|
||||||
int64_t timestamp_us,
|
int64_t timestamp_us,
|
||||||
uint32_t transport_frame_id)
|
uint32_t transport_frame_id);
|
||||||
: VideoFrame(buffer, rotation, timestamp_us) {
|
|
||||||
// For now, transport_frame_id and rtp timestamp are the same.
|
// Alternative constructor, when not knowing or caring about the
|
||||||
// TODO(nisse): Must be handled differently for QUIC.
|
// transport_frame_id. Which is set to zero.
|
||||||
set_timestamp(transport_frame_id);
|
WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
||||||
}
|
webrtc::VideoRotation rotation,
|
||||||
|
int64_t timestamp_us);
|
||||||
|
|
||||||
|
// TODO(nisse): Deprecated, delete as soon as all callers have switched to the
|
||||||
|
// above constructor with microsecond timestamp.
|
||||||
|
WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
|
||||||
|
int64_t timestamp_ns,
|
||||||
|
webrtc::VideoRotation rotation);
|
||||||
|
|
||||||
|
~WebRtcVideoFrame();
|
||||||
|
|
||||||
|
// TODO(nisse): Init (and its helpers Reset and Validate) are used
|
||||||
|
// only by the LoadFrame function used in the VideoFrame unittests.
|
||||||
|
// Rewrite tests, and delete this function.
|
||||||
|
|
||||||
|
// Creates a frame from a raw sample with FourCC "format" and size "w" x "h".
|
||||||
|
// "h" can be negative indicating a vertically flipped image.
|
||||||
|
// "dh" is destination height if cropping is desired and is always positive.
|
||||||
|
// Returns "true" if successful.
|
||||||
|
bool Init(uint32_t format,
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
int dw,
|
||||||
|
int dh,
|
||||||
|
uint8_t* sample,
|
||||||
|
size_t sample_size,
|
||||||
|
int64_t timestamp_ns,
|
||||||
|
webrtc::VideoRotation rotation);
|
||||||
|
|
||||||
|
void InitToEmptyBuffer(int w, int h);
|
||||||
|
|
||||||
|
int width() const override;
|
||||||
|
int height() const override;
|
||||||
|
|
||||||
|
const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& video_frame_buffer()
|
||||||
|
const override;
|
||||||
|
|
||||||
|
uint32_t transport_frame_id() const override;
|
||||||
|
|
||||||
|
int64_t timestamp_us() const override;
|
||||||
|
void set_timestamp_us(int64_t time_us) override;
|
||||||
|
|
||||||
|
webrtc::VideoRotation rotation() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Creates a frame from a raw sample with FourCC |format| and size |w| x |h|.
|
||||||
|
// |h| can be negative indicating a vertically flipped image.
|
||||||
|
// |dw| is destination width; can be less than |w| if cropping is desired.
|
||||||
|
// |dh| is destination height, like |dw|, but must be a positive number.
|
||||||
|
// Returns whether the function succeeded or failed.
|
||||||
|
bool Reset(uint32_t format,
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
int dw,
|
||||||
|
int dh,
|
||||||
|
uint8_t* sample,
|
||||||
|
size_t sample_size,
|
||||||
|
int64_t timestamp_us,
|
||||||
|
webrtc::VideoRotation rotation,
|
||||||
|
bool apply_rotation);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Tests mutate |rotation_|, so the base test class is a friend.
|
||||||
|
friend class WebRtcVideoFrameTest;
|
||||||
|
|
||||||
|
// An opaque reference counted handle that stores the pixel data.
|
||||||
|
rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
|
||||||
|
int64_t timestamp_us_;
|
||||||
|
uint32_t transport_frame_id_;
|
||||||
|
webrtc::VideoRotation rotation_;
|
||||||
|
|
||||||
|
// This is mutable as the calculation is expensive but once calculated, it
|
||||||
|
// remains const.
|
||||||
|
mutable std::unique_ptr<VideoFrame> rotated_frame_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
|||||||
157
webrtc/media/engine/webrtcvideoframe_unittest.cc
Normal file
157
webrtc/media/engine/webrtcvideoframe_unittest.cc
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "webrtc/media/base/videoframe_unittest.h"
|
||||||
|
#include "webrtc/media/engine/webrtcvideoframe.h"
|
||||||
|
#include "webrtc/test/fake_texture_frame.h"
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
|
||||||
|
class WebRtcVideoFrameTest : public VideoFrameTest<WebRtcVideoFrame> {
|
||||||
|
public:
|
||||||
|
WebRtcVideoFrameTest() {}
|
||||||
|
|
||||||
|
void SetFrameRotation(WebRtcVideoFrame* frame,
|
||||||
|
webrtc::VideoRotation rotation) {
|
||||||
|
frame->rotation_ = rotation;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TEST_WEBRTCVIDEOFRAME(X) \
|
||||||
|
TEST_F(WebRtcVideoFrameTest, X) { VideoFrameTest<WebRtcVideoFrame>::X(); }
|
||||||
|
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI420)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI422)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYuy2)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYuy2Unaligned)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYuy2Wide)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYV12)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructUyvy)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructM420)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV21)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV12)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructABGR)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructARGB)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructARGBWide)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructBGRA)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(Construct24BG)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructRaw)
|
||||||
|
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI420Mirror)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI420Rotate0)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI420Rotate90)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI420Rotate180)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI420Rotate270)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYV12Rotate0)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYV12Rotate90)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYV12Rotate180)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYV12Rotate270)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV12Rotate0)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV12Rotate90)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV12Rotate180)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV12Rotate270)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV21Rotate0)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV21Rotate90)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV21Rotate180)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructNV21Rotate270)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructUYVYRotate0)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructUYVYRotate90)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructUYVYRotate180)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructUYVYRotate270)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYUY2Rotate0)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYUY2Rotate90)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYUY2Rotate180)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructYUY2Rotate270)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI4201Pixel)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI4205Pixel)
|
||||||
|
// TODO(juberti): WebRtcVideoFrame does not support horizontal crop.
|
||||||
|
// Re-evaluate once it supports 3 independent planes, since we might want to
|
||||||
|
// just Init normally and then crop by adjusting pointers.
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructI420CropHorizontal)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructI420CropVertical)
|
||||||
|
// TODO(juberti): WebRtcVideoFrame is not currently refcounted.
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructCopy)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructCopyIsRef)
|
||||||
|
// TODO(fbarchard): Implement Jpeg
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI420)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ConstructMjpgI422)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI444)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI411)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI400)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ValidateMjpgI420)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ValidateMjpgI422)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ValidateMjpgI444)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ValidateMjpgI411)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ValidateMjpgI400)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ValidateI420)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ValidateI420SmallSize)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ValidateI420LargeSize)
|
||||||
|
TEST_WEBRTCVIDEOFRAME(ValidateI420HugeSize)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ValidateMjpgI420InvalidSize)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ValidateI420InvalidSize)
|
||||||
|
|
||||||
|
// TODO(fbarchard): WebRtcVideoFrame does not support odd sizes.
|
||||||
|
// Re-evaluate once WebRTC switches to libyuv
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructYuy2AllSizes)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructARGBAllSizes)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConvertToI422Buffer)
|
||||||
|
// TEST_WEBRTCVIDEOFRAME(ConstructARGBBlackWhitePixel)
|
||||||
|
|
||||||
|
TEST_F(WebRtcVideoFrameTest, TextureInitialValues) {
|
||||||
|
webrtc::test::FakeNativeHandle* dummy_handle =
|
||||||
|
new webrtc::test::FakeNativeHandle();
|
||||||
|
webrtc::NativeHandleBuffer* buffer =
|
||||||
|
new rtc::RefCountedObject<webrtc::test::FakeNativeHandleBuffer>(
|
||||||
|
dummy_handle, 640, 480);
|
||||||
|
|
||||||
|
WebRtcVideoFrame frame(buffer, webrtc::kVideoRotation_0, 20);
|
||||||
|
EXPECT_EQ(dummy_handle, frame.video_frame_buffer()->native_handle());
|
||||||
|
EXPECT_EQ(640, frame.width());
|
||||||
|
EXPECT_EQ(480, frame.height());
|
||||||
|
EXPECT_EQ(20, frame.timestamp_us());
|
||||||
|
frame.set_timestamp_us(40);
|
||||||
|
EXPECT_EQ(40, frame.timestamp_us());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WebRtcVideoFrameTest, ApplyRotationToFrame) {
|
||||||
|
WebRtcVideoFrame applied0;
|
||||||
|
EXPECT_TRUE(IsNull(applied0));
|
||||||
|
EXPECT_TRUE(LoadFrame(CreateYuvSample(kWidth, kHeight, 12).get(), FOURCC_I420,
|
||||||
|
kWidth, kHeight, &applied0));
|
||||||
|
|
||||||
|
// Claim that this frame needs to be rotated for 90 degree.
|
||||||
|
SetFrameRotation(&applied0, webrtc::kVideoRotation_90);
|
||||||
|
EXPECT_EQ(applied0.rotation(), webrtc::kVideoRotation_90);
|
||||||
|
|
||||||
|
// Apply rotation on frame 1. Output should be different from frame 1.
|
||||||
|
WebRtcVideoFrame applied90(
|
||||||
|
webrtc::I420Buffer::Rotate(applied0.video_frame_buffer(),
|
||||||
|
applied0.rotation()),
|
||||||
|
webrtc::kVideoRotation_0, applied0.timestamp_us());
|
||||||
|
|
||||||
|
EXPECT_EQ(applied90.rotation(), webrtc::kVideoRotation_0);
|
||||||
|
EXPECT_FALSE(IsEqual(applied0, applied90, 0));
|
||||||
|
|
||||||
|
// Claim the frame 2 needs to be rotated for another 270 degree. The output
|
||||||
|
// from frame 2 rotation should be the same as frame 1.
|
||||||
|
SetFrameRotation(&applied90, webrtc::kVideoRotation_270);
|
||||||
|
WebRtcVideoFrame applied360(
|
||||||
|
webrtc::I420Buffer::Rotate(applied90.video_frame_buffer(),
|
||||||
|
applied90.rotation()),
|
||||||
|
webrtc::kVideoRotation_0, applied90.timestamp_us());
|
||||||
|
EXPECT_EQ(applied360.rotation(), webrtc::kVideoRotation_0);
|
||||||
|
EXPECT_TRUE(IsEqual(applied0, applied360, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cricket
|
||||||
@ -60,6 +60,7 @@
|
|||||||
'base/videocapturerfactory.h',
|
'base/videocapturerfactory.h',
|
||||||
'base/videocommon.cc',
|
'base/videocommon.cc',
|
||||||
'base/videocommon.h',
|
'base/videocommon.h',
|
||||||
|
'base/videoframe.cc',
|
||||||
'base/videoframe.h',
|
'base/videoframe.h',
|
||||||
'base/videosourcebase.cc',
|
'base/videosourcebase.cc',
|
||||||
'base/videosourcebase.h',
|
'base/videosourcebase.h',
|
||||||
@ -81,6 +82,7 @@
|
|||||||
'engine/webrtcvideoencoderfactory.h',
|
'engine/webrtcvideoencoderfactory.h',
|
||||||
'engine/webrtcvideoengine2.cc',
|
'engine/webrtcvideoengine2.cc',
|
||||||
'engine/webrtcvideoengine2.h',
|
'engine/webrtcvideoengine2.h',
|
||||||
|
'engine/webrtcvideoframe.cc',
|
||||||
'engine/webrtcvideoframe.h',
|
'engine/webrtcvideoframe.h',
|
||||||
'engine/webrtcvoe.h',
|
'engine/webrtcvoe.h',
|
||||||
'engine/webrtcvoiceengine.cc',
|
'engine/webrtcvoiceengine.cc',
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include "webrtc/base/bind.h"
|
#include "webrtc/base/bind.h"
|
||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/logging.h"
|
|
||||||
#include "webrtc/base/thread.h"
|
#include "webrtc/base/thread.h"
|
||||||
#include "webrtc/common_video/include/corevideo_frame_buffer.h"
|
#include "webrtc/common_video/include/corevideo_frame_buffer.h"
|
||||||
#include "webrtc/common_video/rotation.h"
|
#include "webrtc/common_video/rotation.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user