15f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org/* 25f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * libjingle 35f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * Copyright 2010 Google Inc. 45f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 55f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * Redistribution and use in source and binary forms, with or without 65f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * modification, are permitted provided that the following conditions are met: 75f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 85f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * this list of conditions and the following disclaimer. 105f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * this list of conditions and the following disclaimer in the documentation 125f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * and/or other materials provided with the distribution. 135f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * derived from this software without specific prior written permission. 155f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 165f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org */ 2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "talk/media/base/videocommon.h" 2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <limits.h> // For INT_MAX 3128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <math.h> 3228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <sstream> 3328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 345237aaf243d29732f59557361b7a993c0a18cf0etfarina#include "webrtc/base/arraysize.h" 35d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/common.h" 3628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace cricket { 3828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstruct FourCCAliasEntry { 400c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t alias; 410c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t canonical; 4228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 4328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic const FourCCAliasEntry kFourCCAliases[] = { 4528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_IYUV, FOURCC_I420}, 4628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_YU16, FOURCC_I422}, 4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_YU24, FOURCC_I444}, 4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_YUYV, FOURCC_YUY2}, 4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_YUVS, FOURCC_YUY2}, 5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_HDYC, FOURCC_UYVY}, 5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_2VUY, FOURCC_UYVY}, 5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_JPEG, FOURCC_MJPG}, // Note: JPEG has DHT while MJPG does not. 5328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_DMB1, FOURCC_MJPG}, 5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_BA81, FOURCC_BGGR}, 5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_RGB3, FOURCC_RAW}, 5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_BGR3, FOURCC_24BG}, 5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_CM32, FOURCC_BGRA}, 5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {FOURCC_CM24, FOURCC_RAW}, 5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 610c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmuint32_t CanonicalFourCC(uint32_t fourcc) { 625237aaf243d29732f59557361b7a993c0a18cf0etfarina for (int i = 0; i < arraysize(kFourCCAliases); ++i) { 6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (kFourCCAliases[i].alias == fourcc) { 6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return kFourCCAliases[i].canonical; 6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Not an alias, so return it as-is. 6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return fourcc; 6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic float kScaleFactors[] = { 7228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 1.f / 1.f, // Full size. 7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 1.f / 2.f, // 1/2 scale. 7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 1.f / 4.f, // 1/4 scale. 7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 1.f / 8.f, // 1/8 scale. 7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 1.f / 16.f // 1/16 scale. 7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 795237aaf243d29732f59557361b7a993c0a18cf0etfarinastatic const int kNumScaleFactors = arraysize(kScaleFactors); 8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Finds the scale factor that, when applied to width and height, produces 8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// fewer than num_pixels. 8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic float FindLowerScale(int width, int height, int target_num_pixels) { 8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!target_num_pixels) { 8528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return 0.f; 8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int best_distance = INT_MAX; 8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int best_index = kNumScaleFactors - 1; // Default to max scale. 8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (int i = 0; i < kNumScaleFactors; ++i) { 9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int test_num_pixels = static_cast<int>(width * kScaleFactors[i] * 9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org height * kScaleFactors[i]); 9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int diff = target_num_pixels - test_num_pixels; 9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (diff >= 0 && diff < best_distance) { 9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org best_distance = diff; 9528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org best_index = i; 9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (best_distance == 0) { // Found exact match. 9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 10128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return kScaleFactors[best_index]; 10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 104cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org// Computes a scale less to fit in max_pixels while maintaining aspect ratio. 105cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.orgvoid ComputeScaleMaxPixels(int frame_width, int frame_height, int max_pixels, 106cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org int* scaled_width, int* scaled_height) { 10728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(scaled_width != NULL); 10828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(scaled_height != NULL); 109cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org ASSERT(max_pixels > 0); 11028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const int kMaxWidth = 4096; 11128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const int kMaxHeight = 3072; 11228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int new_frame_width = frame_width; 11328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int new_frame_height = frame_height; 11428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 11528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Limit width. 11628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (new_frame_width > kMaxWidth) { 11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org new_frame_height = new_frame_height * kMaxWidth / new_frame_width; 11828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org new_frame_width = kMaxWidth; 11928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 12028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Limit height. 12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (new_frame_height > kMaxHeight) { 12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org new_frame_width = new_frame_width * kMaxHeight / new_frame_height; 12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org new_frame_height = kMaxHeight; 12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Limit number of pixels. 126cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org if (new_frame_width * new_frame_height > max_pixels) { 12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Compute new width such that width * height is less than maximum but 12828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // maintains original captured frame aspect ratio. 12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org new_frame_width = static_cast<int>(sqrtf(static_cast<float>( 130cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org max_pixels) * new_frame_width / new_frame_height)); 131cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org new_frame_height = max_pixels / new_frame_width; 13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 13328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Snap to a scale factor that is less than or equal to target pixels. 13428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org float scale = FindLowerScale(frame_width, frame_height, 13528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org new_frame_width * new_frame_height); 13628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *scaled_width = static_cast<int>(frame_width * scale + .5f); 13728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *scaled_height = static_cast<int>(frame_height * scale + .5f); 13828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 13928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 140cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org// Compute a size to scale frames to that is below maximum compression 141cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org// and rendering size with the same aspect ratio. 142cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.orgvoid ComputeScale(int frame_width, int frame_height, int fps, 143cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org int* scaled_width, int* scaled_height) { 144cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org // Maximum pixels limit is set to Retina MacBookPro 15" resolution of 145cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org // 2880 x 1800 as of 4/18/2013. 146cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org // For high fps, maximum pixels limit is set based on common 24" monitor 147cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org // resolution of 2048 x 1280 as of 6/13/2013. The Retina resolution is 148cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org // therefore reduced to 1440 x 900. 149cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org int max_pixels = (fps > 5) ? 2048 * 1280 : 2880 * 1800; 150cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org ComputeScaleMaxPixels( 151cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org frame_width, frame_height, max_pixels, scaled_width, scaled_height); 152cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org} 153cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org 15428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Compute size to crop video frame to. 15528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// If cropped_format_* is 0, return the frame_* size as is. 15697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.orgvoid ComputeCrop(int cropped_format_width, int cropped_format_height, 15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int frame_width, int frame_height, 15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int pixel_width, int pixel_height, 15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int rotation, 16028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int* cropped_width, int* cropped_height) { 16197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org // Transform screen crop to camera space if rotated. 16297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org if (rotation == 90 || rotation == 270) { 16397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org std::swap(cropped_format_width, cropped_format_height); 16497077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org } 16528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(cropped_format_width >= 0); 16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(cropped_format_height >= 0); 16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(frame_width > 0); 16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(frame_height > 0); 16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(pixel_width >= 0); 17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(pixel_height >= 0); 17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270); 17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(cropped_width != NULL); 17328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(cropped_height != NULL); 17428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!pixel_width) { 17528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pixel_width = 1; 17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!pixel_height) { 17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pixel_height = 1; 17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // if cropped_format is 0x0 disable cropping. 18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!cropped_format_height) { 18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cropped_format_height = 1; 18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 18428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org float frame_aspect = static_cast<float>(frame_width * pixel_width) / 18528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org static_cast<float>(frame_height * pixel_height); 18628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org float crop_aspect = static_cast<float>(cropped_format_width) / 18728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org static_cast<float>(cropped_format_height); 18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // kAspectThresh is the maximum aspect ratio difference that we'll accept 18997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org // for cropping. The value 1.34 allows cropping from 4:3 to 16:9. 19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Set to zero to disable cropping entirely. 19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(fbarchard): crop to multiple of 16 width for better performance. 19297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org const float kAspectThresh = 1.34f; 19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Wide aspect - crop horizontally 19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (frame_aspect > crop_aspect && 19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org frame_aspect < crop_aspect * kAspectThresh) { 19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Round width down to multiple of 4 to avoid odd chroma width. 19728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Width a multiple of 4 allows a half size image to have chroma channel 19897077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org // that avoids rounding errors. 19997077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org frame_width = static_cast<int>((crop_aspect * frame_height * 20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pixel_height) / pixel_width + 0.5f) & ~3; 20197077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org } else if (frame_aspect < crop_aspect && 20297077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org frame_aspect > crop_aspect / kAspectThresh) { 20397077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org frame_height = static_cast<int>((frame_width * pixel_width) / 20428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (crop_aspect * pixel_height) + 0.5f) & ~1; 20528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20697077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org *cropped_width = frame_width; 20797077a3ab27259164eb121034b6e0ebe9ba592dfwu@webrtc.org *cropped_height = frame_height; 20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 210cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org// Compute the frame size that makes pixels square pixel aspect ratio. 211cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.orgvoid ComputeScaleToSquarePixels(int in_width, int in_height, 212cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org int pixel_width, int pixel_height, 213cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org int* scaled_width, int* scaled_height) { 214cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org *scaled_width = in_width; // Keep width the same. 2151b15f4226ff417095d2146401ca71cd98ab735b3mallinath@webrtc.org *scaled_height = in_height * pixel_height / pixel_width; 216cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org} 217cadf9040cbb9e7bb1b73a95e43e7d228fe6b2bdbwu@webrtc.org 21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// The C++ standard requires a namespace-scope definition of static const 21928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// integral types even when they are initialized in the declaration (see 22028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// [class.static.data]/4), but MSVC with /Ze is non-conforming and treats that 22128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// as a multiply defined symbol error. See Also: 22228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// http://msdn.microsoft.com/en-us/library/34h23df8.aspx 22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifndef _MSC_EXTENSIONS 2240c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmconst int64_t VideoFormat::kMinimumInterval; // Initialized in header. 22528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif 22628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstd::string VideoFormat::ToString() const { 22828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::string fourcc_name = GetFourccName(fourcc) + " "; 22928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (std::string::const_iterator i = fourcc_name.begin(); 23028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org i < fourcc_name.end(); ++i) { 23128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Test character is printable; Avoid isprint() which asserts on negatives. 23228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (*i < 32 || *i >= 127) { 23328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org fourcc_name = ""; 23428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 23528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::ostringstream ss; 2394b26e2eee3e3b2a0c22946372a38f7efa6cee146sergeyu@chromium.org ss << fourcc_name << width << "x" << height << "x" 2404b26e2eee3e3b2a0c22946372a38f7efa6cee146sergeyu@chromium.org << IntervalToFpsFloat(interval); 24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return ss.str(); 24228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 24328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} // namespace cricket 245