summaryrefslogtreecommitdiffstats
path: root/ext/mplex/mpegconsts.cc
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-10-24 22:37:51 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-10-24 22:37:51 +0000
commit1496394c0f4be1a718fb189846c6350cbd9e43da (patch)
tree7f839063fd206ad3db102a7a20c336d0c8423295 /ext/mplex/mpegconsts.cc
parent440801dd9e53284925575c2170b53bf947522414 (diff)
downloadgst-plugins-bad-1496394c0f4be1a718fb189846c6350cbd9e43da.tar.gz
gst-plugins-bad-1496394c0f4be1a718fb189846c6350cbd9e43da.tar.bz2
gst-plugins-bad-1496394c0f4be1a718fb189846c6350cbd9e43da.zip
First stab at porting mplex
Original commit message from CVS: First stab at porting mplex
Diffstat (limited to 'ext/mplex/mpegconsts.cc')
-rw-r--r--ext/mplex/mpegconsts.cc427
1 files changed, 427 insertions, 0 deletions
diff --git a/ext/mplex/mpegconsts.cc b/ext/mplex/mpegconsts.cc
new file mode 100644
index 00000000..2265da3a
--- /dev/null
+++ b/ext/mplex/mpegconsts.cc
@@ -0,0 +1,427 @@
+
+/*
+ * mpegconsts.c: Video format constants for MPEG and utilities for display
+ * and conversion to format used for yuv4mpeg
+ *
+ * Copyright (C) 2001 Andrew Stevens <andrew.stevens@philips.com>
+ * Copyright (C) 2001 Matthew Marjanovic <maddog@mir.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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 <config.h>
+#include "mpegconsts.h"
+#include "yuv4mpeg.h"
+#include "yuv4mpeg_intern.h"
+
+static y4m_ratio_t mpeg_framerates[] = {
+ Y4M_FPS_UNKNOWN,
+ Y4M_FPS_NTSC_FILM,
+ Y4M_FPS_FILM,
+ Y4M_FPS_PAL,
+ Y4M_FPS_NTSC,
+ Y4M_FPS_30,
+ Y4M_FPS_PAL_FIELD,
+ Y4M_FPS_NTSC_FIELD,
+ Y4M_FPS_60
+};
+
+
+#define MPEG_NUM_RATES (sizeof(mpeg_framerates)/sizeof(mpeg_framerates[0]))
+const mpeg_framerate_code_t mpeg_num_framerates = MPEG_NUM_RATES;
+
+static const char *framerate_definitions[MPEG_NUM_RATES] = {
+ "illegal",
+ "24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)",
+ "24.0 (NATIVE FILM)",
+ "25.0 (PAL/SECAM VIDEO / converted FILM)",
+ "30000.0/1001.0 (NTSC VIDEO)",
+ "30.0",
+ "50.0 (PAL FIELD RATE)",
+ "60000.0/1001.0 (NTSC FIELD RATE)",
+ "60.0"
+};
+
+
+static const char *mpeg1_aspect_ratio_definitions[] = {
+ "1:1 (square pixels)",
+ "1:0.6735",
+ "1:0.7031 (16:9 Anamorphic PAL/SECAM for 720x578/352x288 images)",
+ "1:0.7615",
+ "1:0.8055",
+ "1:0.8437 (16:9 Anamorphic NTSC for 720x480/352x240 images)",
+ "1:0.8935",
+ "1:0.9375 (4:3 PAL/SECAM for 720x578/352x288 images)",
+ "1:0.9815",
+ "1:1.0255",
+ "1:1:0695",
+ "1:1.1250 (4:3 NTSC for 720x480/352x240 images)",
+ "1:1.1575",
+ "1:1.2015"
+};
+
+static const y4m_ratio_t mpeg1_aspect_ratios[] = {
+ Y4M_SAR_MPEG1_1,
+ Y4M_SAR_MPEG1_2,
+ Y4M_SAR_MPEG1_3, /* Anamorphic 16:9 PAL */
+ Y4M_SAR_MPEG1_4,
+ Y4M_SAR_MPEG1_5,
+ Y4M_SAR_MPEG1_6, /* Anamorphic 16:9 NTSC */
+ Y4M_SAR_MPEG1_7,
+ Y4M_SAR_MPEG1_8, /* PAL/SECAM 4:3 */
+ Y4M_SAR_MPEG1_9,
+ Y4M_SAR_MPEG1_10,
+ Y4M_SAR_MPEG1_11,
+ Y4M_SAR_MPEG1_12, /* NTSC 4:3 */
+ Y4M_SAR_MPEG1_13,
+ Y4M_SAR_MPEG1_14,
+};
+
+static const char *mpeg2_aspect_ratio_definitions[] = {
+ "1:1 pixels",
+ "4:3 display",
+ "16:9 display",
+ "2.21:1 display"
+};
+
+
+static const y4m_ratio_t mpeg2_aspect_ratios[] = {
+ Y4M_DAR_MPEG2_1,
+ Y4M_DAR_MPEG2_2,
+ Y4M_DAR_MPEG2_3,
+ Y4M_DAR_MPEG2_4
+};
+
+static const char **aspect_ratio_definitions[2] = {
+ mpeg1_aspect_ratio_definitions,
+ mpeg2_aspect_ratio_definitions
+};
+
+static const y4m_ratio_t *mpeg_aspect_ratios[2] = {
+ mpeg1_aspect_ratios,
+ mpeg2_aspect_ratios
+};
+
+const mpeg_aspect_code_t mpeg_num_aspect_ratios[2] = {
+ sizeof (mpeg1_aspect_ratios) / sizeof (mpeg1_aspect_ratios[0]),
+ sizeof (mpeg2_aspect_ratios) / sizeof (mpeg2_aspect_ratios[0])
+};
+
+/*
+ * Convert MPEG frame-rate code to corresponding frame-rate
+ */
+
+y4m_ratio_t
+mpeg_framerate (mpeg_framerate_code_t code)
+{
+ if (code == 0 || code > mpeg_num_framerates)
+ return y4m_fps_UNKNOWN;
+ else
+ return mpeg_framerates[code];
+}
+
+/*
+ * Look-up MPEG frame rate code for a (exact) frame rate.
+ */
+
+
+mpeg_framerate_code_t
+mpeg_framerate_code (y4m_ratio_t framerate)
+{
+ mpeg_framerate_code_t i;
+
+ y4m_ratio_reduce (&framerate);
+ for (i = 1; i < mpeg_num_framerates; ++i) {
+ if (Y4M_RATIO_EQL (framerate, mpeg_framerates[i]))
+ return i;
+ }
+ return 0;
+}
+
+
+/* small enough to distinguish 1/1000 from 1/1001 */
+#define MPEG_FPS_TOLERANCE 0.0001
+
+
+y4m_ratio_t
+mpeg_conform_framerate (double fps)
+{
+ mpeg_framerate_code_t i;
+ y4m_ratio_t result;
+
+ /* try to match it to a standard frame rate */
+ for (i = 1; i < mpeg_num_framerates; i++) {
+ double deviation = 1.0 - (Y4M_RATIO_DBL (mpeg_framerates[i]) / fps);
+
+ if ((deviation > -MPEG_FPS_TOLERANCE) && (deviation < +MPEG_FPS_TOLERANCE))
+ return mpeg_framerates[i];
+ }
+ /* no luck? just turn it into a ratio (6 decimal place accuracy) */
+ result.n = (int) ((fps * 1000000.0) + 0.5);
+ result.d = 1000000;
+ y4m_ratio_reduce (&result);
+ return result;
+}
+
+
+
+/*
+ * Convert MPEG aspect-ratio code to corresponding aspect-ratio
+ */
+
+y4m_ratio_t
+mpeg_aspect_ratio (int mpeg_version, mpeg_aspect_code_t code)
+{
+ y4m_ratio_t ratio;
+
+ if (mpeg_version < 1 || mpeg_version > 2)
+ return y4m_sar_UNKNOWN;
+ if (code == 0 || code > mpeg_num_aspect_ratios[mpeg_version - 1])
+ return y4m_sar_UNKNOWN;
+ else {
+ ratio = mpeg_aspect_ratios[mpeg_version - 1][code - 1];
+ y4m_ratio_reduce (&ratio);
+ return ratio;
+ }
+}
+
+/*
+ * Look-up corresponding MPEG aspect ratio code given an exact aspect ratio.
+ *
+ * WARNING: The semantics of aspect ratio coding *changed* between
+ * MPEG1 and MPEG2. In MPEG1 it is the *pixel* aspect ratio. In
+ * MPEG2 it is the (far more sensible) aspect ratio of the eventual
+ * display.
+ *
+ */
+
+mpeg_aspect_code_t
+mpeg_frame_aspect_code (int mpeg_version, y4m_ratio_t aspect_ratio)
+{
+ mpeg_aspect_code_t i;
+ y4m_ratio_t red_ratio = aspect_ratio;
+
+ y4m_ratio_reduce (&red_ratio);
+ if (mpeg_version < 1 || mpeg_version > 2)
+ return 0;
+ for (i = 1; i < mpeg_num_aspect_ratios[mpeg_version - 1]; ++i) {
+ y4m_ratio_t red_entry = mpeg_aspect_ratios[mpeg_version - 1][i - 1];
+
+ y4m_ratio_reduce (&red_entry);
+ if (Y4M_RATIO_EQL (red_entry, red_ratio))
+ return i;
+ }
+
+ return 0;
+
+}
+
+
+
+/*
+ * Guess the correct MPEG aspect ratio code,
+ * given the true sample aspect ratio and frame size of a video stream
+ * (and the MPEG version, 1 or 2).
+ *
+ * Returns 0 if it has no good guess.
+ *
+ */
+
+
+/* this is big enough to accommodate the difference between 720 and 704 */
+#define GUESS_ASPECT_TOLERANCE 0.03
+
+mpeg_aspect_code_t
+mpeg_guess_mpeg_aspect_code (int mpeg_version, y4m_ratio_t sampleaspect,
+ int frame_width, int frame_height)
+{
+ if (Y4M_RATIO_EQL (sampleaspect, y4m_sar_UNKNOWN)) {
+ return 0;
+ }
+ switch (mpeg_version) {
+ case 1:
+ if (Y4M_RATIO_EQL (sampleaspect, y4m_sar_SQUARE)) {
+ return 1;
+ } else if (Y4M_RATIO_EQL (sampleaspect, y4m_sar_NTSC_CCIR601)) {
+ return 12;
+ } else if (Y4M_RATIO_EQL (sampleaspect, y4m_sar_NTSC_16_9)) {
+ return 6;
+ } else if (Y4M_RATIO_EQL (sampleaspect, y4m_sar_PAL_CCIR601)) {
+ return 8;
+ } else if (Y4M_RATIO_EQL (sampleaspect, y4m_sar_PAL_16_9)) {
+ return 3;
+ }
+ return 0;
+ break;
+ case 2:
+ if (Y4M_RATIO_EQL (sampleaspect, y4m_sar_SQUARE)) {
+ return 1; /* '1' means square *pixels* in MPEG-2; go figure. */
+ } else {
+ unsigned int i;
+ double true_far; /* true frame aspect ratio */
+
+ true_far =
+ (double) (sampleaspect.n * frame_width) / (double) (sampleaspect.d * frame_height);
+ /* start at '2'... */
+ for (i = 2; i < mpeg_num_aspect_ratios[mpeg_version - 1]; i++) {
+ double ratio = true_far / Y4M_RATIO_DBL (mpeg_aspect_ratios[mpeg_version - 1][i - 1]);
+
+ if ((ratio > (1.0 - GUESS_ASPECT_TOLERANCE)) && (ratio < (1.0 + GUESS_ASPECT_TOLERANCE)))
+ return i;
+ }
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+
+
+
+/*
+ * Guess the true sample aspect ratio of a video stream,
+ * given the MPEG aspect ratio code and the actual frame size
+ * (and the MPEG version, 1 or 2).
+ *
+ * Returns y4m_sar_UNKNOWN if it has no good guess.
+ *
+ */
+y4m_ratio_t
+mpeg_guess_sample_aspect_ratio (int mpeg_version,
+ mpeg_aspect_code_t code, int frame_width, int frame_height)
+{
+ switch (mpeg_version) {
+ case 1:
+ /* MPEG-1 codes turn into SAR's, just not quite the right ones.
+ For the common/known values, we provide the ratio used in practice,
+ otherwise say we don't know. */
+ switch (code) {
+ case 1:
+ return y4m_sar_SQUARE;
+ break;
+ case 3:
+ return y4m_sar_PAL_16_9;
+ break;
+ case 6:
+ return y4m_sar_NTSC_16_9;
+ break;
+ case 8:
+ return y4m_sar_PAL_CCIR601;
+ break;
+ case 12:
+ return y4m_sar_NTSC_CCIR601;
+ break;
+ default:
+ return y4m_sar_UNKNOWN;
+ break;
+ }
+ break;
+ case 2:
+ /* MPEG-2 codes turn into Frame Aspect Ratios, though not exactly the
+ FAR's used in practice. For common/standard frame sizes, we provide
+ the original SAR; otherwise, we say we don't know. */
+ if (code == 1) {
+ return y4m_sar_SQUARE; /* '1' means square *pixels* in MPEG-2 */
+ } else if ((code >= 2) && (code <= 4)) {
+ return y4m_guess_sar (frame_width, frame_height, mpeg2_aspect_ratios[code - 1]);
+ } else {
+ return y4m_sar_UNKNOWN;
+ }
+ break;
+ default:
+ return y4m_sar_UNKNOWN;
+ break;
+ }
+}
+
+
+
+
+
+/*
+ * Look-up MPEG explanatory definition string for frame rate code
+ *
+ */
+
+
+const char *
+mpeg_framerate_code_definition (mpeg_framerate_code_t code)
+{
+ if (code == 0 || code >= mpeg_num_framerates)
+ return "UNDEFINED: illegal/reserved frame-rate ratio code";
+
+ return framerate_definitions[code];
+}
+
+/*
+ * Look-up MPEG explanatory definition string aspect ratio code for an
+ * aspect ratio code
+ *
+ */
+
+const char *
+mpeg_aspect_code_definition (int mpeg_version, mpeg_aspect_code_t code)
+{
+ if (mpeg_version < 1 || mpeg_version > 2)
+ return "UNDEFINED: illegal MPEG version";
+
+ if (code < 1 || code > mpeg_num_aspect_ratios[mpeg_version - 1])
+ return "UNDEFINED: illegal aspect ratio code";
+
+ return aspect_ratio_definitions[mpeg_version - 1][code - 1];
+}
+
+
+/*
+ * Look-up explanatory definition of interlace field order code
+ *
+ */
+
+const char *
+mpeg_interlace_code_definition (int yuv4m_interlace_code)
+{
+ const char *def;
+
+ switch (yuv4m_interlace_code) {
+ case Y4M_UNKNOWN:
+ def = "unknown";
+ break;
+ case Y4M_ILACE_NONE:
+ def = "none/progressive";
+ break;
+ case Y4M_ILACE_TOP_FIRST:
+ def = "top-field-first";
+ break;
+ case Y4M_ILACE_BOTTOM_FIRST:
+ def = "bottom-field-first";
+ break;
+ default:
+ def = "UNDEFINED: illegal video interlacing type-code!";
+ break;
+ }
+ return def;
+}
+
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */