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