videoframe.cc revision bdcf38c89446b1b464a646414f6cd7573a190bd1
128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/*
228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * libjingle
328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Copyright 2011 Google Inc.
428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *
528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *
828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     this list of conditions and the following disclaimer.
1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
1128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     and/or other materials provided with the distribution.
1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *     derived from this software without specific prior written permission.
1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *
1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
1728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
1928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */
2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "talk/media/base/videoframe.h"
2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
30371243dfa3467c7be7217da4b537cc33d2bd45a6pbos@webrtc.org#include <string.h>
3128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
3228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#if !defined(DISABLE_YUV)
3328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "libyuv/compare.h"
3428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "libyuv/planar_functions.h"
3528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "libyuv/scale.h"
3628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif
3728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
3828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "talk/media/base/videocommon.h"
39a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/logging.h"
4028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
4128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace cricket {
4228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
4328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Round to 2 pixels because Chroma channels are half size.
4428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define ROUNDTO2(v) (v & ~1)
4528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
46d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgrtc::StreamResult VideoFrame::Write(rtc::StreamInterface* stream,
4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                          int* error) {
48d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  rtc::StreamResult result = rtc::SR_SUCCESS;
4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const uint8* src_y = GetYPlane();
5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const uint8* src_u = GetUPlane();
5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const uint8* src_v = GetVPlane();
5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!src_y || !src_u || !src_v) {
5328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return result;  // Nothing to write.
5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const int32 y_pitch = GetYPitch();
5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const int32 u_pitch = GetUPitch();
5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const int32 v_pitch = GetVPitch();
5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const size_t width = GetWidth();
5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const size_t height = GetHeight();
6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const size_t half_width = (width + 1) >> 1;
6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const size_t half_height = (height + 1) >> 1;
6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Write Y.
6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (size_t row = 0; row < height; ++row) {
6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    result = stream->Write(src_y + row * y_pitch, width, NULL, error);
65d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    if (result != rtc::SR_SUCCESS) {
6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return result;
6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Write U.
7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (size_t row = 0; row < half_height; ++row) {
7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    result = stream->Write(src_u + row * u_pitch, half_width, NULL, error);
72d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    if (result != rtc::SR_SUCCESS) {
7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return result;
7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Write V.
7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (size_t row = 0; row < half_height; ++row) {
7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    result = stream->Write(src_v + row * v_pitch, half_width, NULL, error);
79d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    if (result != rtc::SR_SUCCESS) {
8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      return result;
8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return result;
8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
8528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool VideoFrame::CopyToPlanes(
8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    uint8* dst_y, uint8* dst_u, uint8* dst_v,
8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int32 dst_pitch_y, int32 dst_pitch_u, int32 dst_pitch_v) const {
8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#if !defined(DISABLE_YUV)
9028654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org  int32 src_width = static_cast<int>(GetWidth());
9128654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org  int32 src_height = static_cast<int>(GetHeight());
9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return libyuv::I420Copy(GetYPlane(), GetYPitch(),
9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          GetUPlane(), GetUPitch(),
9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          GetVPlane(), GetVPitch(),
9528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          dst_y, dst_pitch_y,
9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          dst_u, dst_pitch_u,
9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          dst_v, dst_pitch_v,
9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          src_width, src_height) == 0;
9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#else
10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  int uv_size = GetUPitch() * GetChromaHeight();
10128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  memcpy(dst_y, GetYPlane(), GetWidth() * GetHeight());
10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  memcpy(dst_u, GetUPlane(), uv_size);
10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  memcpy(dst_v, GetVPlane(), uv_size);
10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
10528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif
10628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
10728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
10828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid VideoFrame::CopyToFrame(VideoFrame* dst) const {
10928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!dst) {
11028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "NULL dst pointer.";
11128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return;
11228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
11328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
11428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  CopyToPlanes(dst->GetYPlane(), dst->GetUPlane(), dst->GetVPlane(),
11528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org               dst->GetYPitch(), dst->GetUPitch(), dst->GetVPitch());
11628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
118bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.orgsize_t VideoFrame::ConvertToRgbBuffer(uint32 to_fourcc,
119bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org                                      uint8* buffer,
120bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org                                      size_t size,
121bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org                                      int stride_rgb) const {
122bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org  const size_t needed = std::abs(stride_rgb) * GetHeight();
123bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org  if (size < needed) {
124bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org    LOG(LS_WARNING) << "RGB buffer is not large enough";
125bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org    return needed;
126bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org  }
127bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org
128bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org  if (libyuv::ConvertFromI420(GetYPlane(), GetYPitch(), GetUPlane(),
129bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org                              GetUPitch(), GetVPlane(), GetVPitch(), buffer,
130bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org                              stride_rgb, static_cast<int>(GetWidth()),
131bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org                              static_cast<int>(GetHeight()), to_fourcc)) {
132bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org    LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc;
133bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org    return 0;  // 0 indicates error
134bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org  }
135bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org  return needed;
136bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org}
137bdcf38c89446b1b464a646414f6cd7573a190bd1magjed@webrtc.org
13828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// TODO(fbarchard): Handle odd width/height with rounding.
13928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid VideoFrame::StretchToPlanes(
14028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    uint8* dst_y, uint8* dst_u, uint8* dst_v,
14128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    int32 dst_pitch_y, int32 dst_pitch_u, int32 dst_pitch_v,
14228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    size_t width, size_t height, bool interpolate, bool vert_crop) const {
14328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!GetYPlane() || !GetUPlane() || !GetVPlane()) {
14428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "NULL plane pointer.";
14528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return;
14628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
14728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
14828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  size_t src_width = GetWidth();
14928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  size_t src_height = GetHeight();
15028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (width == src_width && height == src_height) {
15128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    CopyToPlanes(dst_y, dst_u, dst_v, dst_pitch_y, dst_pitch_u, dst_pitch_v);
15228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return;
15328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
15428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const uint8* src_y = GetYPlane();
15528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const uint8* src_u = GetUPlane();
15628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  const uint8* src_v = GetVPlane();
15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (vert_crop) {
15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Adjust the input width:height ratio to be the same as the output ratio.
16028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (src_width * height > src_height * width) {
16128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      // Reduce the input width, but keep size/position aligned for YuvScaler
16228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_width = ROUNDTO2(src_height * width / height);
16328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      int32 iwidth_offset = ROUNDTO2((GetWidth() - src_width) / 2);
16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_y += iwidth_offset;
16528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_u += iwidth_offset / 2;
16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_v += iwidth_offset / 2;
16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    } else if (src_width * height < src_height * width) {
16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      // Reduce the input height.
16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_height = src_width * height / width;
17028654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org      int32 iheight_offset = static_cast<int32>(
17128654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org          (GetHeight() - src_height) >> 2);
17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      iheight_offset <<= 1;  // Ensure that iheight_offset is even.
17328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_y += iheight_offset * GetYPitch();
17428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_u += iheight_offset / 2 * GetUPitch();
17528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      src_v += iheight_offset / 2 * GetVPitch();
17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(fbarchard): Implement a simple scale for non-libyuv.
18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#if !defined(DISABLE_YUV)
18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Scale to the output I420 frame.
18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  libyuv::Scale(src_y, src_u, src_v,
18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                GetYPitch(), GetUPitch(), GetVPitch(),
18428654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                static_cast<int>(src_width), static_cast<int>(src_height),
18528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                dst_y, dst_u, dst_v, dst_pitch_y, dst_pitch_u, dst_pitch_v,
18628654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                static_cast<int>(width), static_cast<int>(height), interpolate);
18728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif
18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgsize_t VideoFrame::StretchToBuffer(size_t dst_width, size_t dst_height,
19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                   uint8* dst_buffer, size_t size,
19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                   bool interpolate, bool vert_crop) const {
19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!dst_buffer) {
19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "NULL dst_buffer pointer.";
19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return 0;
19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
19728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
19828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  size_t needed = SizeOf(dst_width, dst_height);
19928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (needed <= size) {
20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    uint8* dst_y = dst_buffer;
20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    uint8* dst_u = dst_y + dst_width * dst_height;
20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    uint8* dst_v = dst_u + ((dst_width + 1) >> 1) * ((dst_height + 1) >> 1);
20328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    StretchToPlanes(dst_y, dst_u, dst_v,
20428654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                    static_cast<int32>(dst_width),
20528654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                    static_cast<int32>((dst_width + 1) >> 1),
20628654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                    static_cast<int32>((dst_width + 1) >> 1),
20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    dst_width, dst_height, interpolate, vert_crop);
20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return needed;
21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid VideoFrame::StretchToFrame(VideoFrame* dst,
21328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                bool interpolate, bool vert_crop) const {
21428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!dst) {
21528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "NULL dst pointer.";
21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return;
21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
21928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  StretchToPlanes(dst->GetYPlane(), dst->GetUPlane(), dst->GetVPlane(),
22028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  dst->GetYPitch(), dst->GetUPitch(), dst->GetVPitch(),
22128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  dst->GetWidth(), dst->GetHeight(),
22228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  interpolate, vert_crop);
22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  dst->SetElapsedTime(GetElapsedTime());
22428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  dst->SetTimeStamp(GetTimeStamp());
22528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
22628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
22728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgVideoFrame* VideoFrame::Stretch(size_t dst_width, size_t dst_height,
22828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                bool interpolate, bool vert_crop) const {
22928654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org  VideoFrame* dest = CreateEmptyFrame(static_cast<int>(dst_width),
23028654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                                      static_cast<int>(dst_height),
23128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      GetPixelWidth(), GetPixelHeight(),
23228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                      GetElapsedTime(), GetTimeStamp());
23328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (dest) {
23428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    StretchToFrame(dest, interpolate, vert_crop);
23528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return dest;
23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
23928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool VideoFrame::SetToBlack() {
24028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#if !defined(DISABLE_YUV)
24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return libyuv::I420Rect(GetYPlane(), GetYPitch(),
24228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          GetUPlane(), GetUPitch(),
24328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          GetVPlane(), GetVPitch(),
24428654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                          0, 0,
24528654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                          static_cast<int>(GetWidth()),
24628654cbc2256230c978f41cbaf550bc2e9c2f2dbhenrike@webrtc.org                          static_cast<int>(GetHeight()),
24728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          16, 128, 128) == 0;
24828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#else
24928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  int uv_size = GetUPitch() * GetChromaHeight();
25028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  memset(GetYPlane(), 16, GetWidth() * GetHeight());
25128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  memset(GetUPlane(), 128, uv_size);
25228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  memset(GetVPlane(), 128, uv_size);
25328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
25428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif
25528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
25628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
25728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic const size_t kMaxSampleSize = 1000000000u;
2587e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com// Returns whether a sample is valid.
25928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool VideoFrame::Validate(uint32 fourcc, int w, int h,
26028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                          const uint8 *sample, size_t sample_size) {
26128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (h < 0) {
26228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    h = -h;
26328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
26428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // 16384 is maximum resolution for VP8 codec.
26528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (w < 1 || w > 16384 || h < 1 || h > 16384) {
26628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "Invalid dimensions: " << w << "x" << h;
26728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
26828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
26928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  uint32 format = CanonicalFourCC(fourcc);
27028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  int expected_bpp = 8;
27128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  switch (format) {
27228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_I400:
27328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_RGGB:
27428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_BGGR:
27528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_GRBG:
27628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_GBRG:
27728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      expected_bpp = 8;
27828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
27928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_I420:
28028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_I411:
28128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_YU12:
28228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_YV12:
28328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_M420:
28428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_Q420:
28528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_NV21:
28628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_NV12:
28728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      expected_bpp = 12;
28828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
28928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_I422:
29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_YV16:
29128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_YUY2:
29228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_UYVY:
29328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_RGBP:
29428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_RGBO:
29528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_R444:
29628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      expected_bpp = 16;
29728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
29828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_I444:
29928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_YV24:
30028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_24BG:
30128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_RAW:
30228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      expected_bpp = 24;
30328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
30428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
30528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_ABGR:
30628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_BGRA:
30728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_ARGB:
30828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      expected_bpp = 32;
30928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
31028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
31128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_MJPG:
31228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    case FOURCC_H264:
31328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      expected_bpp = 0;
31428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
31528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    default:
31628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      expected_bpp = 8;  // Expect format is at least 8 bits per pixel.
31728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
31828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
31928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  size_t expected_size = (w * expected_bpp + 7) / 8 * h;
32028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // For compressed formats, expect 4 bits per 16 x 16 macro.  I420 would be
32128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // 6 bits, but grey can be 4 bits.
32228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (expected_bpp == 0) {
32328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    expected_size = ((w + 15) / 16) * ((h + 15) / 16) * 4 / 8;
32428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
32528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (sample == NULL) {
32628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "NULL sample pointer."
32728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " format: " << GetFourccName(format)
32828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " bpp: " << expected_bpp
32928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " size: " << w << "x" << h
33028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " expected: " << expected_size
33128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " " << sample_size;
33228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
33328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
3347e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com  // TODO(fbarchard): Make function to dump information about frames.
3357e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com  uint8 four_samples[4] = { 0, 0, 0, 0 };
3367e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com  for (size_t i = 0; i < ARRAY_SIZE(four_samples) && i < sample_size; ++i) {
3377e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com    four_samples[i] = sample[i];
3387e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com  }
33928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (sample_size < expected_size) {
34028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "Size field is too small."
34128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " format: " << GetFourccName(format)
34228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " bpp: " << expected_bpp
34328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " size: " << w << "x" << h
34428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " " << sample_size
34528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                  << " expected: " << expected_size
3467e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                  << " sample[0..3]: " << static_cast<int>(four_samples[0])
3477e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                  << ", " << static_cast<int>(four_samples[1])
3487e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                  << ", " << static_cast<int>(four_samples[2])
3497e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                  << ", " << static_cast<int>(four_samples[3]);
35028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
35128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (sample_size > kMaxSampleSize) {
35328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_WARNING) << "Size field is invalid."
35428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " format: " << GetFourccName(format)
35528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " bpp: " << expected_bpp
35628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " size: " << w << "x" << h
35728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " " << sample_size
35828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " expected: " << 2 * expected_size
3597e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << " sample[0..3]: " << static_cast<int>(four_samples[0])
3607e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << ", " << static_cast<int>(four_samples[1])
3617e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << ", " << static_cast<int>(four_samples[2])
3627e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << ", " << static_cast<int>(four_samples[3]);
36328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
36428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
36528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Show large size warning once every 100 frames.
3667e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com  // TODO(fbarchard): Make frame counter atomic for thread safety.
36728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static int large_warn100 = 0;
36828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  size_t large_expected_size = expected_size * 2;
36928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (expected_bpp >= 8 &&
37028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      (sample_size > large_expected_size || sample_size > kMaxSampleSize) &&
37128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      large_warn100 % 100 == 0) {
37228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    ++large_warn100;
37328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_WARNING) << "Size field is too large."
37428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " format: " << GetFourccName(format)
37528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " bpp: " << expected_bpp
37628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " size: " << w << "x" << h
37728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " bytes: " << sample_size
37828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                    << " expected: " << large_expected_size
3797e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << " sample[0..3]: " << static_cast<int>(four_samples[0])
3807e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << ", " << static_cast<int>(four_samples[1])
3817e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << ", " << static_cast<int>(four_samples[2])
3827e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                    << ", " << static_cast<int>(four_samples[3]);
38328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
3857e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com  // TODO(fbarchard): Add duplicate pixel check.
3867e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com  // TODO(fbarchard): Use frame counter atomic for thread safety.
38728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  static bool valid_once = true;
38828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (valid_once) {
38928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    valid_once = false;
39028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_INFO) << "Validate frame passed."
39128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << " format: " << GetFourccName(format)
39228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << " bpp: " << expected_bpp
39328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << " size: " << w << "x" << h
39428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << " bytes: " << sample_size
39528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << " expected: " << expected_size
3967e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                 << " sample[0..3]: " << static_cast<int>(four_samples[0])
3977e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                 << ", " << static_cast<int>(four_samples[1])
3987e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                 << ", " << static_cast<int>(four_samples[2])
3997e31197cb23e32dacaa7c0dd479d0cf21a23cfb8fbarchard@google.com                 << ", " << static_cast<int>(four_samples[3]);
40028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
40128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
40228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
40328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
40428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}  // namespace cricket
405