Reason for revert: Fixed downstream issue. Original issue's description: > Revert of Delete method cricket::VideoFrame::Copy. (patchset #3 id:210001 of https://codereview.webrtc.org/2275243002/ ) > > Reason for revert: > Again, brakes a downstream build by removing VideoFrame::Copy method. > > Original issue's description: > > Reland of Delete method cricket::VideoFrame::Copy. (patchset #1 id:1 of https://codereview.webrtc.org/2087923004/ ) > > > > Reason for revert: > > Downstream issue now fixed. > > > > Original issue's description: > > > Revert of Delete method cricket::VideoFrame::Copy. (patchset #7 id:120001 of https://codereview.webrtc.org/2080253002/ ) > > > > > > Reason for revert: > > > It broke a downstream build by removing VideoFrame::Copy method. > > > > > > Original issue's description: > > > > Delete method cricket::VideoFrame::Copy. > > > > > > > > Should be unused in Chrome since cl > > > > https://codereview.chromium.org/2068703002/ > > > > > > > > TBR=tkchin@webrtc.org,magjed@webrtc.org > > > > BUG=webrtc:5682 > > > > > > > > Committed: https://crrev.com/9c00f646f0b3cd33506a1944c7bc6724af041237 > > > > Committed: https://crrev.com/7e4e00d189a5dfac2b463a5100ee65ee2f11ed79 > > > > Cr-Original-Commit-Position: refs/heads/master@{#13236} > > > > Cr-Commit-Position: refs/heads/master@{#13244} > > > > > > TBR=pbos@webrtc.org,tkchin@webrtc.org,magjed@webrtc.org,sergeyu@chromium.org,nisse@webrtc.org > > > # Skipping CQ checks because original CL landed less than 1 days ago. > > > NOPRESUBMIT=true > > > NOTREECHECKS=true > > > NOTRY=true > > > BUG=webrtc:5682 > > > > > > Committed: https://crrev.com/123f33cd009606d22cca8b0f4756812406d4580f > > > Cr-Commit-Position: refs/heads/master@{#13246} > > > > TBR=pbos@webrtc.org,tkchin@webrtc.org,magjed@webrtc.org,sergeyu@chromium.org,honghaiz@webrtc.org > > # Not skipping CQ checks because original CL landed more than 1 days ago. > > BUG=webrtc:5682 > > > > Committed: https://crrev.com/f715f983f1b33208ab2d2434f8b36ad5271f680f > > Cr-Commit-Position: refs/heads/master@{#13924} > > TBR=pbos@webrtc.org,tkchin@webrtc.org,magjed@webrtc.org,sergeyu@chromium.org,honghaiz@webrtc.org,nisse@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5682 > > Committed: https://crrev.com/91b03b0ff8c480e4245835c7a4a93733aac534a6 > Cr-Commit-Position: refs/heads/master@{#13925} TBR=pbos@webrtc.org,tkchin@webrtc.org,magjed@webrtc.org,sergeyu@chromium.org,honghaiz@webrtc.org,philipel@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5682 Review-Url: https://codereview.webrtc.org/2287223002 Cr-Commit-Position: refs/heads/master@{#13949}
227 lines
7.7 KiB
C++
227 lines
7.7 KiB
C++
/*
|
|
* 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"
|
|
|
|
using webrtc::kYPlane;
|
|
using webrtc::kUPlane;
|
|
using webrtc::kVPlane;
|
|
|
|
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*/);
|
|
}
|
|
|
|
bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh,
|
|
bool apply_rotation) {
|
|
return Reset(frame->fourcc, frame->width, frame->height, dw, dh,
|
|
static_cast<uint8_t*>(frame->data), frame->data_size,
|
|
frame->time_stamp / rtc::kNumNanosecsPerMicrosec,
|
|
frame->rotation, 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_;
|
|
}
|
|
|
|
size_t WebRtcVideoFrame::ConvertToRgbBuffer(uint32_t to_fourcc,
|
|
uint8_t* buffer,
|
|
size_t size,
|
|
int stride_rgb) const {
|
|
RTC_CHECK(video_frame_buffer_);
|
|
RTC_CHECK(video_frame_buffer_->native_handle() == nullptr);
|
|
return VideoFrame::ConvertToRgbBuffer(to_fourcc, buffer, size, stride_rgb);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
InitToEmptyBuffer(new_width, new_height);
|
|
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,
|
|
video_frame_buffer_->MutableDataY(),
|
|
video_frame_buffer_->StrideY(),
|
|
video_frame_buffer_->MutableDataU(),
|
|
video_frame_buffer_->StrideU(),
|
|
video_frame_buffer_->MutableDataV(),
|
|
video_frame_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_ = new rtc::RefCountedObject<webrtc::I420Buffer>(w, h);
|
|
rotation_ = webrtc::kVideoRotation_0;
|
|
}
|
|
|
|
const VideoFrame* WebRtcVideoFrame::GetCopyWithRotationApplied() const {
|
|
// If the frame is not rotated, the caller should reuse this frame instead of
|
|
// making a redundant copy.
|
|
if (rotation() == webrtc::kVideoRotation_0) {
|
|
return this;
|
|
}
|
|
|
|
// If the video frame is backed up by a native handle, it resides in the GPU
|
|
// memory which we can't rotate here. The assumption is that the renderers
|
|
// which uses GPU to render should be able to rotate themselves.
|
|
RTC_DCHECK(!video_frame_buffer()->native_handle());
|
|
|
|
if (rotated_frame_) {
|
|
return rotated_frame_.get();
|
|
}
|
|
|
|
int current_width = width();
|
|
int current_height = height();
|
|
|
|
int rotated_width = current_width;
|
|
int rotated_height = current_height;
|
|
if (rotation() == webrtc::kVideoRotation_90 ||
|
|
rotation() == webrtc::kVideoRotation_270) {
|
|
std::swap(rotated_width, rotated_height);
|
|
}
|
|
|
|
rtc::scoped_refptr<webrtc::I420Buffer> buffer =
|
|
new rtc::RefCountedObject<webrtc::I420Buffer>(rotated_width,
|
|
rotated_height);
|
|
|
|
// TODO(guoweis): Add a function in webrtc_libyuv.cc to convert from
|
|
// VideoRotation to libyuv::RotationMode.
|
|
int ret = libyuv::I420Rotate(
|
|
video_frame_buffer_->DataY(), video_frame_buffer_->StrideY(),
|
|
video_frame_buffer_->DataU(), video_frame_buffer_->StrideU(),
|
|
video_frame_buffer_->DataV(), video_frame_buffer_->StrideV(),
|
|
buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(),
|
|
buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(),
|
|
current_width, current_height,
|
|
static_cast<libyuv::RotationMode>(rotation()));
|
|
if (ret == 0) {
|
|
rotated_frame_.reset(new WebRtcVideoFrame(
|
|
buffer, webrtc::kVideoRotation_0, timestamp_us_, transport_frame_id_));
|
|
}
|
|
|
|
return rotated_frame_.get();
|
|
}
|
|
|
|
} // namespace cricket
|