OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include "webrtc/media/engine/webrtcvideoframe.h" |
| 12 |
| 13 #include "libyuv/convert.h" |
| 14 #include "webrtc/base/logging.h" |
| 15 #include "webrtc/media/base/videocapturer.h" |
| 16 #include "webrtc/media/base/videocommon.h" |
| 17 #include "webrtc/video_frame.h" |
| 18 |
| 19 namespace cricket { |
| 20 |
| 21 WebRtcVideoFrame::WebRtcVideoFrame() |
| 22 : timestamp_us_(0), rotation_(webrtc::kVideoRotation_0) {} |
| 23 |
| 24 WebRtcVideoFrame::WebRtcVideoFrame( |
| 25 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, |
| 26 webrtc::VideoRotation rotation, |
| 27 int64_t timestamp_us, |
| 28 uint32_t transport_frame_id) |
| 29 : video_frame_buffer_(buffer), |
| 30 timestamp_us_(timestamp_us), |
| 31 transport_frame_id_(transport_frame_id), |
| 32 rotation_(rotation) {} |
| 33 |
| 34 WebRtcVideoFrame::WebRtcVideoFrame( |
| 35 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, |
| 36 webrtc::VideoRotation rotation, |
| 37 int64_t timestamp_us) |
| 38 : WebRtcVideoFrame(buffer, rotation, timestamp_us, 0) {}; |
| 39 |
| 40 WebRtcVideoFrame::WebRtcVideoFrame( |
| 41 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, |
| 42 int64_t time_stamp_ns, |
| 43 webrtc::VideoRotation rotation) |
| 44 : WebRtcVideoFrame(buffer, |
| 45 rotation, |
| 46 time_stamp_ns / rtc::kNumNanosecsPerMicrosec, |
| 47 0) {} |
| 48 |
| 49 WebRtcVideoFrame::~WebRtcVideoFrame() {} |
| 50 |
| 51 bool WebRtcVideoFrame::Init(uint32_t format, |
| 52 int w, |
| 53 int h, |
| 54 int dw, |
| 55 int dh, |
| 56 uint8_t* sample, |
| 57 size_t sample_size, |
| 58 int64_t time_stamp_ns, |
| 59 webrtc::VideoRotation rotation) { |
| 60 return Reset(format, w, h, dw, dh, sample, sample_size, |
| 61 time_stamp_ns / rtc::kNumNanosecsPerMicrosec, rotation, |
| 62 true /*apply_rotation*/); |
| 63 } |
| 64 |
| 65 int WebRtcVideoFrame::width() const { |
| 66 return video_frame_buffer_ ? video_frame_buffer_->width() : 0; |
| 67 } |
| 68 |
| 69 int WebRtcVideoFrame::height() const { |
| 70 return video_frame_buffer_ ? video_frame_buffer_->height() : 0; |
| 71 } |
| 72 |
| 73 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& |
| 74 WebRtcVideoFrame::video_frame_buffer() const { |
| 75 return video_frame_buffer_; |
| 76 } |
| 77 |
| 78 uint32_t WebRtcVideoFrame::transport_frame_id() const { |
| 79 return transport_frame_id_; |
| 80 } |
| 81 |
| 82 int64_t WebRtcVideoFrame::timestamp_us() const { |
| 83 return timestamp_us_; |
| 84 } |
| 85 |
| 86 void WebRtcVideoFrame::set_timestamp_us(int64_t time_us) { |
| 87 timestamp_us_ = time_us; |
| 88 } |
| 89 |
| 90 webrtc::VideoRotation WebRtcVideoFrame::rotation() const { |
| 91 return rotation_; |
| 92 } |
| 93 |
| 94 bool WebRtcVideoFrame::Reset(uint32_t format, |
| 95 int w, |
| 96 int h, |
| 97 int dw, |
| 98 int dh, |
| 99 uint8_t* sample, |
| 100 size_t sample_size, |
| 101 int64_t timestamp_us, |
| 102 webrtc::VideoRotation rotation, |
| 103 bool apply_rotation) { |
| 104 if (!Validate(format, w, h, sample, sample_size)) { |
| 105 return false; |
| 106 } |
| 107 // Translate aliases to standard enums (e.g., IYUV -> I420). |
| 108 format = CanonicalFourCC(format); |
| 109 |
| 110 // Set up a new buffer. |
| 111 // TODO(fbarchard): Support lazy allocation. |
| 112 int new_width = dw; |
| 113 int new_height = dh; |
| 114 // If rotated swap width, height. |
| 115 if (apply_rotation && (rotation == 90 || rotation == 270)) { |
| 116 new_width = dh; |
| 117 new_height = dw; |
| 118 } |
| 119 |
| 120 rtc::scoped_refptr<webrtc::I420Buffer> buffer = |
| 121 webrtc::I420Buffer::Create(new_width, new_height); |
| 122 video_frame_buffer_ = buffer; |
| 123 rotation_ = apply_rotation ? webrtc::kVideoRotation_0 : rotation; |
| 124 |
| 125 int horiz_crop = ((w - dw) / 2) & ~1; |
| 126 // ARGB on Windows has negative height. |
| 127 // The sample's layout in memory is normal, so just correct crop. |
| 128 int vert_crop = ((abs(h) - dh) / 2) & ~1; |
| 129 // Conversion functions expect negative height to flip the image. |
| 130 int idh = (h < 0) ? -dh : dh; |
| 131 int r = libyuv::ConvertToI420( |
| 132 sample, sample_size, |
| 133 buffer->MutableDataY(), buffer->StrideY(), |
| 134 buffer->MutableDataU(), buffer->StrideU(), |
| 135 buffer->MutableDataV(), buffer->StrideV(), |
| 136 horiz_crop, vert_crop, w, h, dw, idh, |
| 137 static_cast<libyuv::RotationMode>( |
| 138 apply_rotation ? rotation : webrtc::kVideoRotation_0), |
| 139 format); |
| 140 if (r) { |
| 141 LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format) |
| 142 << " return code : " << r; |
| 143 return false; |
| 144 } |
| 145 timestamp_us_ = timestamp_us; |
| 146 return true; |
| 147 } |
| 148 |
| 149 void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h) { |
| 150 video_frame_buffer_ = webrtc::I420Buffer::Create(w, h); |
| 151 rotation_ = webrtc::kVideoRotation_0; |
| 152 } |
| 153 |
| 154 } // namespace cricket |
OLD | NEW |