From 2f0cc8ec30e8c26fed7b2c9ac2614c9a7655fb65 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 26 Jul 2003 03:01:58 +0000 Subject: Moved from gst-plugins/ext/mplex/. See that directory for older changelogs. Original commit message from CVS: Moved from gst-plugins/ext/mplex/. See that directory for older changelogs. --- gst-libs/ext/mplex/yuv4mpeg_ratio.cc | 167 +++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 gst-libs/ext/mplex/yuv4mpeg_ratio.cc (limited to 'gst-libs/ext/mplex/yuv4mpeg_ratio.cc') diff --git a/gst-libs/ext/mplex/yuv4mpeg_ratio.cc b/gst-libs/ext/mplex/yuv4mpeg_ratio.cc new file mode 100644 index 00000000..a20a2373 --- /dev/null +++ b/gst-libs/ext/mplex/yuv4mpeg_ratio.cc @@ -0,0 +1,167 @@ +/* + * yuv4mpeg_ratio.c: Functions for dealing with y4m_ratio_t datatype. + * + * Copyright (C) 2001 Matthew J. Marjanovic + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include + +#include +#include "yuv4mpeg.h" +#include "yuv4mpeg_intern.h" + + +/* useful list of standard framerates */ +const y4m_ratio_t y4m_fps_UNKNOWN = Y4M_FPS_UNKNOWN; +const y4m_ratio_t y4m_fps_NTSC_FILM = Y4M_FPS_NTSC_FILM; +const y4m_ratio_t y4m_fps_FILM = Y4M_FPS_FILM; +const y4m_ratio_t y4m_fps_PAL = Y4M_FPS_PAL; +const y4m_ratio_t y4m_fps_NTSC = Y4M_FPS_NTSC; +const y4m_ratio_t y4m_fps_30 = Y4M_FPS_30; +const y4m_ratio_t y4m_fps_PAL_FIELD = Y4M_FPS_PAL_FIELD; +const y4m_ratio_t y4m_fps_NTSC_FIELD = Y4M_FPS_NTSC_FIELD; +const y4m_ratio_t y4m_fps_60 = Y4M_FPS_60; + +/* useful list of standard sample aspect ratios */ +const y4m_ratio_t y4m_sar_UNKNOWN = Y4M_SAR_UNKNOWN; +const y4m_ratio_t y4m_sar_SQUARE = Y4M_SAR_SQUARE; +const y4m_ratio_t y4m_sar_SQR_ANA_16_9 = Y4M_SAR_SQR_ANA_16_9; +const y4m_ratio_t y4m_sar_NTSC_CCIR601 = Y4M_SAR_NTSC_CCIR601; +const y4m_ratio_t y4m_sar_NTSC_16_9 = Y4M_SAR_NTSC_16_9; +const y4m_ratio_t y4m_sar_NTSC_SVCD_4_3 = Y4M_SAR_NTSC_SVCD_4_3; +const y4m_ratio_t y4m_sar_NTSC_SVCD_16_9 = Y4M_SAR_NTSC_SVCD_16_9; +const y4m_ratio_t y4m_sar_PAL_CCIR601 = Y4M_SAR_PAL_CCIR601; +const y4m_ratio_t y4m_sar_PAL_16_9 = Y4M_SAR_PAL_16_9; +const y4m_ratio_t y4m_sar_PAL_SVCD_4_3 = Y4M_SAR_PAL_SVCD_4_3; +const y4m_ratio_t y4m_sar_PAL_SVCD_16_9 = Y4M_SAR_PAL_SVCD_16_9; + +/* useful list of standard display aspect ratios */ +const y4m_ratio_t y4m_dar_4_3 = Y4M_DAR_4_3; +const y4m_ratio_t y4m_dar_16_9 = Y4M_DAR_16_9; +const y4m_ratio_t y4m_dar_221_100 = Y4M_DAR_221_100; + +/* + * Euler's algorithm for greatest common divisor + */ + +static int +gcd (int a, int b) +{ + a = (a >= 0) ? a : -a; + b = (b >= 0) ? b : -b; + + while (b > 0) { + int x = b; + + b = a % b; + a = x; + } + return a; +} + + +/************************************************************************* + * + * Remove common factors from a ratio + * + *************************************************************************/ + + +void +y4m_ratio_reduce (y4m_ratio_t * r) +{ + int d; + + if ((r->n == 0) && (r->d == 0)) + return; /* "unknown" */ + d = gcd (r->n, r->d); + r->n /= d; + r->d /= d; +} + + + +/************************************************************************* + * + * Parse "nnn:ddd" into a ratio + * + * returns: Y4M_OK - success + * Y4M_ERR_RANGE - range error + * + *************************************************************************/ + +int +y4m_parse_ratio (y4m_ratio_t * r, const char *s) +{ + char *t = strchr (s, ':'); + + if (t == NULL) + return Y4M_ERR_RANGE; + r->n = atoi (s); + r->d = atoi (t + 1); + if (r->d < 0) + return Y4M_ERR_RANGE; + /* 0:0 == unknown, so that is ok, otherwise zero denominator is bad */ + if ((r->d == 0) && (r->n != 0)) + return Y4M_ERR_RANGE; + y4m_ratio_reduce (r); + return Y4M_OK; +} + + + +/************************************************************************* + * + * Guess the true SAR (sample aspect ratio) from a list of commonly + * encountered values, given the "suggested" display aspect ratio, and + * the true frame width and height. + * + * Returns y4m_sar_UNKNOWN if no match is found. + * + *************************************************************************/ + +/* this is big enough to accommodate the difference between 720 and 704 */ +#define GUESS_ASPECT_TOLERANCE 0.03 + +y4m_ratio_t +y4m_guess_sar (int width, int height, y4m_ratio_t dar) +{ + int i; + double implicit_sar = (double) (dar.n * height) / (double) (dar.d * width); + y4m_ratio_t sarray[] = { + y4m_sar_SQUARE, + y4m_sar_NTSC_CCIR601, + y4m_sar_NTSC_16_9, + y4m_sar_NTSC_SVCD_4_3, + y4m_sar_NTSC_SVCD_16_9, + y4m_sar_PAL_CCIR601, + y4m_sar_PAL_16_9, + y4m_sar_PAL_SVCD_4_3, + y4m_sar_PAL_SVCD_16_9, + y4m_sar_UNKNOWN + }; + + for (i = 0; !(Y4M_RATIO_EQL (sarray[i], y4m_sar_UNKNOWN)); i++) { + double ratio = implicit_sar / Y4M_RATIO_DBL (sarray[i]); + + if ((ratio > (1.0 - GUESS_ASPECT_TOLERANCE)) && (ratio < (1.0 + GUESS_ASPECT_TOLERANCE))) + return sarray[i]; + } + return y4m_sar_UNKNOWN; +} -- cgit v1.2.1