1043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org/*
2043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org *
4043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org *  Use of this source code is governed by a BSD-style license
5043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org *  that can be found in the LICENSE file in the root of the source
6043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org *  tree. An additional intellectual property rights grant can be found
7043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org *  in the file PATENTS.  All contributing project authors may
8043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org */
10043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
119bfe3daf7349b62647997ced9389baa8ab043afeThiago Farina#include "webrtc/video_frame.h"
12043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
13637c55f45be7a56478f399c7e62e9be06947cd80wuchengli@chromium.org#include <string.h>
14637c55f45be7a56478f399c7e62e9be06947cd80wuchengli@chromium.org
15043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org#include <algorithm>  // swap
16043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
179b3f56ea055934a5d5416db0386c857494410accPer#include "webrtc/base/bind.h"
182386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org#include "webrtc/base/checks.h"
192386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org
20043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.orgnamespace webrtc {
21043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
2267e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychenbool EqualPlane(const uint8_t* data1,
2367e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen                const uint8_t* data2,
2467e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen                int stride,
2567e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen                int width,
2667e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen                int height) {
2767e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen  for (int y = 0; y < height; ++y) {
2867e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen    if (memcmp(data1, data2, width) != 0)
2967e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen      return false;
3067e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen    data1 += stride;
3167e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen    data2 += stride;
3267e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen  }
3367e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen  return true;
3467e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen}
3567e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen
3667e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychenint ExpectedSize(int plane_stride, int image_height, PlaneType type) {
37a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen  if (type == kYPlane)
38a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen    return plane_stride * image_height;
39a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen  return plane_stride * ((image_height + 1) / 2);
4067e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen}
4167e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen
424765070b8d6f024509c717c04d9b708750666927Miguel Casas-SanchezVideoFrame::VideoFrame() {
430d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  // Intentionally using Reset instead of initializer list so that any missed
440d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  // fields in Reset will be caught by memory checkers.
450d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  Reset();
461226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org}
47043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
484765070b8d6f024509c717c04d9b708750666927Miguel Casas-SanchezVideoFrame::VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
494765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                       uint32_t timestamp,
504765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                       int64_t render_time_ms,
514765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                       VideoRotation rotation)
522386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org    : video_frame_buffer_(buffer),
532386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org      timestamp_(timestamp),
542386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org      ntp_time_ms_(0),
552386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org      render_time_ms_(render_time_ms),
562386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org      rotation_(rotation) {
572386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org}
582386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org
594765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::CreateEmptyFrame(int width,
604765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                                 int height,
614765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                                 int stride_y,
624765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                                 int stride_u,
634765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                                 int stride_v) {
642386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  const int half_width = (width + 1) / 2;
6591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GT(width, 0);
6691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GT(height, 0);
6791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GE(stride_y, width);
6891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GE(stride_u, half_width);
6991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_GE(stride_v, half_width);
705a477a0bc6fd3657eb7173d2c8a2e1a01a88dbb3pbos@webrtc.org
719fedff7c17a8d3dc46ed5b3207220f59a22391d6mikhal@webrtc.org  // Creating empty frame - reset all values.
729fedff7c17a8d3dc46ed5b3207220f59a22391d6mikhal@webrtc.org  timestamp_ = 0;
736c75c989648018a1537bb29d41fbcb730b143c15wu@webrtc.org  ntp_time_ms_ = 0;
749fedff7c17a8d3dc46ed5b3207220f59a22391d6mikhal@webrtc.org  render_time_ms_ = 0;
751226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org  rotation_ = kVideoRotation_0;
762386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org
772386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  // Check if it's safe to reuse allocation.
784765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez  if (video_frame_buffer_ && video_frame_buffer_->HasOneRef() &&
792386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org      !video_frame_buffer_->native_handle() &&
802386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org      width == video_frame_buffer_->width() &&
814765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez      height == video_frame_buffer_->height() && stride_y == stride(kYPlane) &&
824765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez      stride_u == stride(kUPlane) && stride_v == stride(kVPlane)) {
832386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org    return 0;
842386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  }
852386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org
862386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  // Need to allocate new buffer.
872386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  video_frame_buffer_ = new rtc::RefCountedObject<I420Buffer>(
882386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org      width, height, stride_y, stride_u, stride_v);
89043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org  return 0;
90043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org}
91043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
924765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::CreateFrame(const uint8_t* buffer_y,
934765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            const uint8_t* buffer_u,
944765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            const uint8_t* buffer_v,
954765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int width,
964765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int height,
974765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int stride_y,
984765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int stride_u,
994765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int stride_v) {
1004765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez  return CreateFrame(buffer_y, buffer_u, buffer_v, width, height, stride_y,
1014765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                     stride_u, stride_v, kVideoRotation_0);
1024765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez}
1034765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez
1044765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::CreateFrame(const uint8_t* buffer_y,
1054765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            const uint8_t* buffer_u,
1064765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            const uint8_t* buffer_v,
1074765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int width,
1084765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int height,
1094765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int stride_y,
1104765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int stride_u,
1114765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int stride_v,
1124765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            VideoRotation rotation) {
1132386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  const int half_height = (height + 1) / 2;
1142386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  const int expected_size_y = height * stride_y;
1152386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  const int expected_size_u = half_height * stride_u;
1162386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  const int expected_size_v = half_height * stride_v;
1175a477a0bc6fd3657eb7173d2c8a2e1a01a88dbb3pbos@webrtc.org  CreateEmptyFrame(width, height, stride_y, stride_u, stride_v);
1182386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  memcpy(buffer(kYPlane), buffer_y, expected_size_y);
1192386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  memcpy(buffer(kUPlane), buffer_u, expected_size_u);
1202386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  memcpy(buffer(kVPlane), buffer_v, expected_size_v);
1211226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org  rotation_ = rotation;
122043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org  return 0;
123043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org}
124043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
1254765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::CreateFrame(const uint8_t* buffer,
1264765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int width,
1274765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            int height,
1284765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                            VideoRotation rotation) {
1299f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org  const int stride_y = width;
1309f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org  const int stride_uv = (width + 1) / 2;
1319f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org
1329f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org  const uint8_t* buffer_y = buffer;
1339f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org  const uint8_t* buffer_u = buffer_y + stride_y * height;
1349f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org  const uint8_t* buffer_v = buffer_u + stride_uv * ((height + 1) / 2);
1359f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org  return CreateFrame(buffer_y, buffer_u, buffer_v, width, height, stride_y,
1369f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org                     stride_uv, stride_uv, rotation);
1379f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org}
1389f9ea7e5abc3fa561e6b190b45219f2416c8786bperkj@webrtc.org
1394765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::CopyFrame(const VideoFrame& videoFrame) {
1406231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org  if (videoFrame.IsZeroSize()) {
1416231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org    video_frame_buffer_ = nullptr;
1426231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org  } else if (videoFrame.native_handle()) {
1432386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org    video_frame_buffer_ = videoFrame.video_frame_buffer();
1442386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  } else {
1456231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org    CreateFrame(videoFrame.buffer(kYPlane), videoFrame.buffer(kUPlane),
1466231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org                videoFrame.buffer(kVPlane), videoFrame.width(),
1476231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org                videoFrame.height(), videoFrame.stride(kYPlane),
1486231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org                videoFrame.stride(kUPlane), videoFrame.stride(kVPlane));
1492386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  }
1506231fb6dac8276581e4ed0f7cb70712d6b6711aapbos@webrtc.org
151043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org  timestamp_ = videoFrame.timestamp_;
1526c75c989648018a1537bb29d41fbcb730b143c15wu@webrtc.org  ntp_time_ms_ = videoFrame.ntp_time_ms_;
153043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org  render_time_ms_ = videoFrame.render_time_ms_;
1541226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org  rotation_ = videoFrame.rotation_;
155043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org  return 0;
156043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org}
157043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
1584765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezvoid VideoFrame::ShallowCopy(const VideoFrame& videoFrame) {
159af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org  video_frame_buffer_ = videoFrame.video_frame_buffer();
160af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org  timestamp_ = videoFrame.timestamp_;
161af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org  ntp_time_ms_ = videoFrame.ntp_time_ms_;
162af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org  render_time_ms_ = videoFrame.render_time_ms_;
163af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org  rotation_ = videoFrame.rotation_;
164af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org}
165af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org
1664765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezvoid VideoFrame::Reset() {
1670d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  video_frame_buffer_ = nullptr;
1680d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  timestamp_ = 0;
1690d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  ntp_time_ms_ = 0;
1700d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  render_time_ms_ = 0;
1710d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org  rotation_ = kVideoRotation_0;
1720d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org}
1730d9bb8e499f52a53292fdb6dfa7dc956f6bff85bmagjed@webrtc.org
1744765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezuint8_t* VideoFrame::buffer(PlaneType type) {
1753318f984cd7f51d24da4726665c05f5f06f82e6dMagnus Jedvert  return video_frame_buffer_ ? video_frame_buffer_->MutableData(type)
1763318f984cd7f51d24da4726665c05f5f06f82e6dMagnus Jedvert                             : nullptr;
17760ac6a642a97b71abae3220fb430b0755ba0d825mikhal@webrtc.org}
17860ac6a642a97b71abae3220fb430b0755ba0d825mikhal@webrtc.org
1794765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezconst uint8_t* VideoFrame::buffer(PlaneType type) const {
1803318f984cd7f51d24da4726665c05f5f06f82e6dMagnus Jedvert  return video_frame_buffer_ ? video_frame_buffer_->data(type) : nullptr;
181043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org}
182043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
1834765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::allocated_size(PlaneType type) const {
1842386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  const int plane_height = (type == kYPlane) ? height() : (height() + 1) / 2;
1852386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  return plane_height * stride(type);
186043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org}
187043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
1884765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::stride(PlaneType type) const {
1892386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  return video_frame_buffer_ ? video_frame_buffer_->stride(type) : 0;
190c8895aa2f31e05d3bd4d29507af3bbfcaa638499magjed@webrtc.org}
1919dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org
1924765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::width() const {
1932386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  return video_frame_buffer_ ? video_frame_buffer_->width() : 0;
194043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org}
195043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org
1964765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint VideoFrame::height() const {
1972386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  return video_frame_buffer_ ? video_frame_buffer_->height() : 0;
1982386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org}
1991f94407319f85abc286c993774a4ea93807ec32etommi@webrtc.org
2004765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezbool VideoFrame::IsZeroSize() const {
2012386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  return !video_frame_buffer_;
202c8895aa2f31e05d3bd4d29507af3bbfcaa638499magjed@webrtc.org}
203c8895aa2f31e05d3bd4d29507af3bbfcaa638499magjed@webrtc.org
2044765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezvoid* VideoFrame::native_handle() const {
2052386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  return video_frame_buffer_ ? video_frame_buffer_->native_handle() : nullptr;
2062386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org}
2072386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org
2084765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezrtc::scoped_refptr<VideoFrameBuffer> VideoFrame::video_frame_buffer() const {
2092386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org  return video_frame_buffer_;
21060ac6a642a97b71abae3220fb430b0755ba0d825mikhal@webrtc.org}
21160ac6a642a97b71abae3220fb430b0755ba0d825mikhal@webrtc.org
2124765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezvoid VideoFrame::set_video_frame_buffer(
213d4e7d49628e39baf30e6aefb4536f1cf042e813bmagjed@webrtc.org    const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer) {
214d4e7d49628e39baf30e6aefb4536f1cf042e813bmagjed@webrtc.org  video_frame_buffer_ = buffer;
215d4e7d49628e39baf30e6aefb4536f1cf042e813bmagjed@webrtc.org}
216d4e7d49628e39baf30e6aefb4536f1cf042e813bmagjed@webrtc.org
217eb66e800d1f5f74ab366715d2618fbede8cf3e12Peter BoströmVideoFrame VideoFrame::ConvertNativeToI420Frame() const {
21891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(native_handle());
219eb66e800d1f5f74ab366715d2618fbede8cf3e12Peter Boström  VideoFrame frame;
220eb66e800d1f5f74ab366715d2618fbede8cf3e12Peter Boström  frame.ShallowCopy(*this);
221eb66e800d1f5f74ab366715d2618fbede8cf3e12Peter Boström  frame.set_video_frame_buffer(video_frame_buffer_->NativeToI420Buffer());
222eb66e800d1f5f74ab366715d2618fbede8cf3e12Peter Boström  return frame;
223eb66e800d1f5f74ab366715d2618fbede8cf3e12Peter Boström}
224eb66e800d1f5f74ab366715d2618fbede8cf3e12Peter Boström
22567e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychenbool VideoFrame::EqualsFrame(const VideoFrame& frame) const {
226a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen  if (width() != frame.width() || height() != frame.height() ||
227a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen      stride(kYPlane) != frame.stride(kYPlane) ||
228a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen      stride(kUPlane) != frame.stride(kUPlane) ||
229a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen      stride(kVPlane) != frame.stride(kVPlane) ||
230a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen      timestamp() != frame.timestamp() ||
231a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen      ntp_time_ms() != frame.ntp_time_ms() ||
232a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen      render_time_ms() != frame.render_time_ms()) {
23367e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen    return false;
23467e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen  }
235a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen  const int half_width = (width() + 1) / 2;
236a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen  const int half_height = (height() + 1) / 2;
237a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen  return EqualPlane(buffer(kYPlane), frame.buffer(kYPlane),
238a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen                    stride(kYPlane), width(), height()) &&
239a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen         EqualPlane(buffer(kUPlane), frame.buffer(kUPlane),
240a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen                    stride(kUPlane), half_width, half_height) &&
241a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen         EqualPlane(buffer(kVPlane), frame.buffer(kVPlane),
242a276e731683c673388cf3aeaa1888a5bcc3e1dc0jackychen                    stride(kVPlane), half_width, half_height);
24367e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen}
24467e94fb6f2a84cad97ba96abce3506c29f8ebb24jackychen
245043ed9ecbd31ea6f53eaa5e9ed319140ec66d1b1mikhal@webrtc.org}  // namespace webrtc
246