1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#include "webrtc/common_video/interface/i420_video_frame.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 131bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include <string.h> 141bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <algorithm> // swap 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgI420VideoFrame::I420VideoFrame() 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : width_(0), 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org height_(0), 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org timestamp_(0), 239d10769e109601915022fea44ec392645c3b0704wu@webrtc.org ntp_time_ms_(0), 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org render_time_ms_(0) {} 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgI420VideoFrame::~I420VideoFrame() {} 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::CreateEmptyFrame(int width, int height, 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int stride_y, int stride_u, int stride_v) { 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CheckDimensions(width, height, stride_y, stride_u, stride_v) < 0) 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int size_y = stride_y * height; 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int half_height = (height + 1) / 2; 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int size_u = stride_u * half_height; 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int size_v = stride_v * half_height; 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org width_ = width; 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org height_ = height; 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org y_plane_.CreateEmptyPlane(size_y, stride_y, size_y); 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org u_plane_.CreateEmptyPlane(size_u, stride_u, size_u); 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org v_plane_.CreateEmptyPlane(size_v, stride_v, size_v); 413bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org // Creating empty frame - reset all values. 423bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org timestamp_ = 0; 439d10769e109601915022fea44ec392645c3b0704wu@webrtc.org ntp_time_ms_ = 0; 443bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org render_time_ms_ = 0; 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::CreateFrame(int size_y, const uint8_t* buffer_y, 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int size_u, const uint8_t* buffer_u, 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int size_v, const uint8_t* buffer_v, 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int width, int height, 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int stride_y, int stride_u, int stride_v) { 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (size_y < 1 || size_u < 1 || size_v < 1) 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CheckDimensions(width, height, stride_y, stride_u, stride_v) < 0) 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org y_plane_.Copy(size_y, stride_y, buffer_y); 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org u_plane_.Copy(size_u, stride_u, buffer_u); 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org v_plane_.Copy(size_v, stride_v, buffer_v); 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org width_ = width; 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org height_ = height; 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::CopyFrame(const I420VideoFrame& videoFrame) { 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int ret = CreateFrame(videoFrame.allocated_size(kYPlane), 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.buffer(kYPlane), 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.allocated_size(kUPlane), 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.buffer(kUPlane), 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.allocated_size(kVPlane), 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.buffer(kVPlane), 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.width_, videoFrame.height_, 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.stride(kYPlane), videoFrame.stride(kUPlane), 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org videoFrame.stride(kVPlane)); 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ret < 0) 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ret; 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org timestamp_ = videoFrame.timestamp_; 789d10769e109601915022fea44ec392645c3b0704wu@webrtc.org ntp_time_ms_ = videoFrame.ntp_time_ms_; 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org render_time_ms_ = videoFrame.render_time_ms_; 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 831bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.orgI420VideoFrame* I420VideoFrame::CloneFrame() const { 841bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org scoped_ptr<I420VideoFrame> new_frame(new I420VideoFrame()); 851bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org if (new_frame->CopyFrame(*this) == -1) { 861bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org // CopyFrame failed. 871bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org return NULL; 881bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org } 891bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org return new_frame.release(); 901bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org} 911bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid I420VideoFrame::SwapFrame(I420VideoFrame* videoFrame) { 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org y_plane_.Swap(videoFrame->y_plane_); 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org u_plane_.Swap(videoFrame->u_plane_); 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org v_plane_.Swap(videoFrame->v_plane_); 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::swap(width_, videoFrame->width_); 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::swap(height_, videoFrame->height_); 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::swap(timestamp_, videoFrame->timestamp_); 999d10769e109601915022fea44ec392645c3b0704wu@webrtc.org std::swap(ntp_time_ms_, videoFrame->ntp_time_ms_); 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::swap(render_time_ms_, videoFrame->render_time_ms_); 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orguint8_t* I420VideoFrame::buffer(PlaneType type) { 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Plane* plane_ptr = GetPlane(type); 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (plane_ptr) 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return plane_ptr->buffer(); 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst uint8_t* I420VideoFrame::buffer(PlaneType type) const { 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Plane* plane_ptr = GetPlane(type); 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (plane_ptr) 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return plane_ptr->buffer(); 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::allocated_size(PlaneType type) const { 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Plane* plane_ptr = GetPlane(type); 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (plane_ptr) 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return plane_ptr->allocated_size(); 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::stride(PlaneType type) const { 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const Plane* plane_ptr = GetPlane(type); 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (plane_ptr) 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return plane_ptr->stride(); 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::set_width(int width) { 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CheckDimensions(width, height_, 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org y_plane_.stride(), u_plane_.stride(), 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org v_plane_.stride()) < 0) 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org width_ = width; 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::set_height(int height) { 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CheckDimensions(width_, height, 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org y_plane_.stride(), u_plane_.stride(), 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org v_plane_.stride()) < 0) 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org height_ = height; 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1493bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgbool I420VideoFrame::IsZeroSize() const { 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (y_plane_.IsZeroSize() && u_plane_.IsZeroSize() && 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org v_plane_.IsZeroSize()); 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid I420VideoFrame::ResetSize() { 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org y_plane_.ResetSize(); 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org u_plane_.ResetSize(); 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org v_plane_.ResetSize(); 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 160ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.orgvoid* I420VideoFrame::native_handle() const { return NULL; } 161ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint I420VideoFrame::CheckDimensions(int width, int height, 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int stride_y, int stride_u, int stride_v) { 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int half_width = (width + 1) / 2; 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (width < 1 || height < 1 || 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org stride_y < width || stride_u < half_width || stride_v < half_width) 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst Plane* I420VideoFrame::GetPlane(PlaneType type) const { 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (type) { 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kYPlane : 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return &y_plane_; 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kUPlane : 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return &u_plane_; 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kVPlane : 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return &v_plane_; 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(false); 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPlane* I420VideoFrame::GetPlane(PlaneType type) { 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (type) { 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kYPlane : 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return &y_plane_; 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kUPlane : 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return &u_plane_; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kVPlane : 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return &v_plane_; 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(false); 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 200