📄 mpegconsts.c
字号:
/* * 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_tmpeg_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]))static 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[] ={ "illegal", "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_UNKNOWN, 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[] = { "illegal", "1:1 pixels", "4:3 display", "16:9 display", "2.21:1 display"};static const y4m_ratio_t mpeg2_aspect_ratios[] ={ Y4M_DAR_UNKNOWN, 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};static 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])};/* * Is code a valid MPEG framerate code? */intmpeg_valid_framerate_code( mpeg_framerate_code_t code ){ return ((code > 0) && (code < mpeg_num_framerates)) ? 1 : 0;}/* * Convert MPEG frame-rate code to corresponding frame-rate */y4m_ratio_tmpeg_framerate( mpeg_framerate_code_t code ){ if ((code > 0) && (code < mpeg_num_framerates)) return mpeg_framerates[code]; else return y4m_fps_UNKNOWN;}/* * 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); /* start at '1', because 0 is unknown/illegal */ 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.0001y4m_ratio_tmpeg_conform_framerate( double fps ){ mpeg_framerate_code_t i; y4m_ratio_t result; /* try to match it to a standard frame rate */ /* (start at '1', because 0 is unknown/illegal) */ 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;} /* * Is code a valid MPEG aspect-ratio code? */intmpeg_valid_aspect_code( int version, mpeg_framerate_code_t c ){ if ((version == 1) || (version == 2)) return ((c > 0) && (c < mpeg_num_aspect_ratios[version-1])) ? 1 : 0; else return 0;}/* * 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) && (code > 0) && (code < mpeg_num_aspect_ratios[mpeg_version-1])) { ratio = mpeg_aspect_ratios[mpeg_version-1][code]; y4m_ratio_reduce(&ratio); return ratio; } else return y4m_sar_UNKNOWN;}/* * 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; /* (start at '1', because 0 is unknown/illegal) */ for( i = 1; i < mpeg_num_aspect_ratios[mpeg_version-1]; ++i ) { y4m_ratio_t red_entry = mpeg_aspect_ratios[mpeg_version-1][i]; 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.03mpeg_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 { 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 < (int)(mpeg_num_aspect_ratios[mpeg_version-1]); i++) { double ratio = true_far / Y4M_RATIO_DBL(mpeg_aspect_ratios[mpeg_version-1][i]); 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 Display Aspect Ratios, though not exactly the DAR'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]); } 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];}/* * 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: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -