mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-23 16:20:03 +01:00
mjpeg , add c files
git-svn-id: svn://code.dyne.org/veejay/trunk@1321 eb8d1916-c9e9-0310-b8de-cf0c9472ead5
This commit is contained in:
512
veejay-current/veejay-client/src/mpegconsts.c
Normal file
512
veejay-current/veejay-client/src/mpegconsts.c
Normal file
@@ -0,0 +1,512 @@
|
||||
|
||||
/*
|
||||
* 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"
|
||||
#include "format_codes.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]))
|
||||
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])
|
||||
};
|
||||
|
||||
static const char *mjpegtools_format_code_definitions[MPEG_FORMAT_LAST+1] =
|
||||
{
|
||||
"Generic MPEG1",
|
||||
"Standard VCD",
|
||||
"Stretched VCD",
|
||||
"Generic MPEG2",
|
||||
"Standard SVCD",
|
||||
"Stretched SVCD",
|
||||
"VCD Still",
|
||||
"SVCD Still",
|
||||
"DVD with dummy navigation packets",
|
||||
"Standard DVD",
|
||||
"ATSC 480i",
|
||||
"ATSC 480p",
|
||||
"ATSC 720p",
|
||||
"ATSC 1080i"
|
||||
};
|
||||
|
||||
/*
|
||||
* Is code a valid MPEG framerate code?
|
||||
*/
|
||||
|
||||
int
|
||||
mpeg_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_t
|
||||
mpeg_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.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 */
|
||||
/* (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 (8 decimal place accuracy) */
|
||||
result.n = (int)((fps * 100000000.0) + 0.5);
|
||||
result.d = 100000000;
|
||||
y4m_ratio_reduce(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Is code a valid MPEG aspect-ratio code?
|
||||
*/
|
||||
|
||||
int
|
||||
mpeg_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.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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look-up explanatory definition of mjepgtools preset format code
|
||||
*
|
||||
*/
|
||||
const char *mpeg_format_code_defintion( int format_code )
|
||||
{
|
||||
if(format_code >= MPEG_FORMAT_FIRST && format_code <= MPEG_FORMAT_LAST )
|
||||
return mjpegtools_format_code_definitions[format_code];
|
||||
else
|
||||
return "UNDEFINED: illegal format code!";
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user