1
2 /*
3 * mpegconsts.c: Video format constants for MPEG and utilities for display
4 * and conversion to format used for yuv4mpeg
5 *
6 * Copyright (C) 2001 Andrew Stevens <andrew.stevens@philips.com>
7 * Copyright (C) 2001 Matthew Marjanovic <maddog@mir.com>
8 *
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public License
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #include <config.h>
25 #include "mpegconsts.h"
26 #include "yuv4mpeg.h"
27 #include "yuv4mpeg_intern.h"
28 #include "format_codes.h"
29
30 static y4m_ratio_t
31 mpeg_framerates[] = {
32 Y4M_FPS_UNKNOWN,
33 Y4M_FPS_NTSC_FILM,
34 Y4M_FPS_FILM,
35 Y4M_FPS_PAL,
36 Y4M_FPS_NTSC,
37 Y4M_FPS_30,
38 Y4M_FPS_PAL_FIELD,
39 Y4M_FPS_NTSC_FIELD,
40 Y4M_FPS_60
41 };
42
43
44 #define MPEG_NUM_RATES (sizeof(mpeg_framerates)/sizeof(mpeg_framerates[0]))
45 static const mpeg_framerate_code_t mpeg_num_framerates = MPEG_NUM_RATES;
46
47 static const char *
48 framerate_definitions[MPEG_NUM_RATES] =
49 {
50 "illegal",
51 "24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)",
52 "24.0 (NATIVE FILM)",
53 "25.0 (PAL/SECAM VIDEO / converted FILM)",
54 "30000.0/1001.0 (NTSC VIDEO)",
55 "30.0",
56 "50.0 (PAL FIELD RATE)",
57 "60000.0/1001.0 (NTSC FIELD RATE)",
58 "60.0"
59 };
60
61
62 static const char *mpeg1_aspect_ratio_definitions[] =
63 {
64 "illegal",
65 "1:1 (square pixels)",
66 "1:0.6735",
67 "1:0.7031 (16:9 Anamorphic PAL/SECAM for 720x578/352x288 images)",
68 "1:0.7615",
69 "1:0.8055",
70 "1:0.8437 (16:9 Anamorphic NTSC for 720x480/352x240 images)",
71 "1:0.8935",
72 "1:0.9375 (4:3 PAL/SECAM for 720x578/352x288 images)",
73 "1:0.9815",
74 "1:1.0255",
75 "1:1:0695",
76 "1:1.1250 (4:3 NTSC for 720x480/352x240 images)",
77 "1:1.1575",
78 "1:1.2015"
79 };
80
81 static const y4m_ratio_t mpeg1_aspect_ratios[] =
82 {
83 Y4M_SAR_UNKNOWN,
84 Y4M_SAR_MPEG1_1,
85 Y4M_SAR_MPEG1_2,
86 Y4M_SAR_MPEG1_3, /* Anamorphic 16:9 PAL */
87 Y4M_SAR_MPEG1_4,
88 Y4M_SAR_MPEG1_5,
89 Y4M_SAR_MPEG1_6, /* Anamorphic 16:9 NTSC */
90 Y4M_SAR_MPEG1_7,
91 Y4M_SAR_MPEG1_8, /* PAL/SECAM 4:3 */
92 Y4M_SAR_MPEG1_9,
93 Y4M_SAR_MPEG1_10,
94 Y4M_SAR_MPEG1_11,
95 Y4M_SAR_MPEG1_12, /* NTSC 4:3 */
96 Y4M_SAR_MPEG1_13,
97 Y4M_SAR_MPEG1_14,
98 };
99
100 static const char *mpeg2_aspect_ratio_definitions[] =
101 {
102 "illegal",
103 "1:1 pixels",
104 "4:3 display",
105 "16:9 display",
106 "2.21:1 display"
107 };
108
109
110 static const y4m_ratio_t mpeg2_aspect_ratios[] =
111 {
112 Y4M_DAR_UNKNOWN,
113 Y4M_DAR_MPEG2_1,
114 Y4M_DAR_MPEG2_2,
115 Y4M_DAR_MPEG2_3,
116 Y4M_DAR_MPEG2_4
117 };
118
119 static const char **aspect_ratio_definitions[2] =
120 {
121 mpeg1_aspect_ratio_definitions,
122 mpeg2_aspect_ratio_definitions
123 };
124
125 static const y4m_ratio_t *mpeg_aspect_ratios[2] =
126 {
127 mpeg1_aspect_ratios,
128 mpeg2_aspect_ratios
129 };
130
131 static const mpeg_aspect_code_t mpeg_num_aspect_ratios[2] =
132 {
133 sizeof(mpeg1_aspect_ratios)/sizeof(mpeg1_aspect_ratios[0]),
134 sizeof(mpeg2_aspect_ratios)/sizeof(mpeg2_aspect_ratios[0])
135 };
136
137 static const char *mjpegtools_format_code_definitions[MPEG_FORMAT_LAST+1] =
138 {
139 "Generic MPEG1",
140 "Standard VCD",
141 "Stretched VCD",
142 "Generic MPEG2",
143 "Standard SVCD",
144 "Stretched SVCD",
145 "VCD Still",
146 "SVCD Still",
147 "DVD with dummy navigation packets",
148 "Standard DVD",
149 "ATSC 480i",
150 "ATSC 480p",
151 "ATSC 720p",
152 "ATSC 1080i"
153 };
154
155 /*
156 * Is code a valid MPEG framerate code?
157 */
158
159 int
mpeg_valid_framerate_code(mpeg_framerate_code_t code)160 mpeg_valid_framerate_code( mpeg_framerate_code_t code )
161 {
162 return ((code > 0) && (code < mpeg_num_framerates)) ? 1 : 0;
163 }
164
165
166 /*
167 * Convert MPEG frame-rate code to corresponding frame-rate
168 */
169
170 y4m_ratio_t
mpeg_framerate(mpeg_framerate_code_t code)171 mpeg_framerate( mpeg_framerate_code_t code )
172 {
173 if ((code > 0) && (code < mpeg_num_framerates))
174 return mpeg_framerates[code];
175 else
176 return y4m_fps_UNKNOWN;
177 }
178
179 /*
180 * Look-up MPEG frame rate code for a (exact) frame rate.
181 */
182
183
184 mpeg_framerate_code_t
mpeg_framerate_code(y4m_ratio_t framerate)185 mpeg_framerate_code( y4m_ratio_t framerate )
186 {
187 mpeg_framerate_code_t i;
188
189 y4m_ratio_reduce(&framerate);
190 /* start at '1', because 0 is unknown/illegal */
191 for (i = 1; i < mpeg_num_framerates; ++i) {
192 if (Y4M_RATIO_EQL(framerate, mpeg_framerates[i]))
193 return i;
194 }
195 return 0;
196 }
197
198
199 /* small enough to distinguish 1/1000 from 1/1001 */
200 #define MPEG_FPS_TOLERANCE 0.0001
201
202
203 y4m_ratio_t
mpeg_conform_framerate(double fps)204 mpeg_conform_framerate( double fps )
205 {
206 mpeg_framerate_code_t i;
207 y4m_ratio_t result;
208
209 /* try to match it to a standard frame rate */
210 /* (start at '1', because 0 is unknown/illegal) */
211 for (i = 1; i < mpeg_num_framerates; i++)
212 {
213 double deviation = 1.0 - (Y4M_RATIO_DBL(mpeg_framerates[i]) / fps);
214 if ( (deviation > -MPEG_FPS_TOLERANCE) &&
215 (deviation < +MPEG_FPS_TOLERANCE) )
216 return mpeg_framerates[i];
217 }
218 /* no luck? just turn it into a ratio (6 decimal place accuracy) */
219 result.n = (int)((fps * 1000000.0) + 0.5);
220 result.d = 1000000;
221 y4m_ratio_reduce(&result);
222 return result;
223 }
224
225
226
227 /*
228 * Is code a valid MPEG aspect-ratio code?
229 */
230
231 int
mpeg_valid_aspect_code(int version,mpeg_framerate_code_t c)232 mpeg_valid_aspect_code( int version, mpeg_framerate_code_t c )
233 {
234 if ((version == 1) || (version == 2))
235 return ((c > 0) && (c < mpeg_num_aspect_ratios[version-1])) ? 1 : 0;
236 else
237 return 0;
238 }
239
240
241 /*
242 * Convert MPEG aspect-ratio code to corresponding aspect-ratio
243 */
244
245 y4m_ratio_t
mpeg_aspect_ratio(int mpeg_version,mpeg_aspect_code_t code)246 mpeg_aspect_ratio( int mpeg_version, mpeg_aspect_code_t code )
247 {
248 y4m_ratio_t ratio;
249 if ((mpeg_version >= 1) && (mpeg_version <= 2) &&
250 (code > 0) && (code < mpeg_num_aspect_ratios[mpeg_version-1]))
251 {
252 ratio = mpeg_aspect_ratios[mpeg_version-1][code];
253 y4m_ratio_reduce(&ratio);
254 return ratio;
255 }
256 else
257 return y4m_sar_UNKNOWN;
258 }
259
260
261
262 /*
263 * Look-up corresponding MPEG aspect ratio code given an exact aspect ratio.
264 *
265 * WARNING: The semantics of aspect ratio coding *changed* between
266 * MPEG1 and MPEG2. In MPEG1 it is the *pixel* aspect ratio. In
267 * MPEG2 it is the (far more sensible) aspect ratio of the eventual
268 * display.
269 *
270 */
271
272 mpeg_aspect_code_t
mpeg_frame_aspect_code(int mpeg_version,y4m_ratio_t aspect_ratio)273 mpeg_frame_aspect_code( int mpeg_version, y4m_ratio_t aspect_ratio )
274 {
275 mpeg_aspect_code_t i;
276 y4m_ratio_t red_ratio = aspect_ratio;
277 y4m_ratio_reduce( &red_ratio );
278 if( mpeg_version < 1 || mpeg_version > 2 )
279 return 0;
280 /* (start at '1', because 0 is unknown/illegal) */
281 for( i = 1; i < mpeg_num_aspect_ratios[mpeg_version-1]; ++i )
282 {
283 y4m_ratio_t red_entry = mpeg_aspect_ratios[mpeg_version-1][i];
284 y4m_ratio_reduce( &red_entry );
285 if( Y4M_RATIO_EQL( red_entry, red_ratio) )
286 return i;
287 }
288
289 return 0;
290
291 }
292
293
294
295 /*
296 * Guess the correct MPEG aspect ratio code,
297 * given the true sample aspect ratio and frame size of a video stream
298 * (and the MPEG version, 1 or 2).
299 *
300 * Returns 0 if it has no good guess.
301 *
302 */
303
304
305 /* this is big enough to accommodate the difference between 720 and 704 */
306 #define GUESS_ASPECT_TOLERANCE 0.03
307
308 mpeg_aspect_code_t
mpeg_guess_mpeg_aspect_code(int mpeg_version,y4m_ratio_t sampleaspect,int frame_width,int frame_height)309 mpeg_guess_mpeg_aspect_code(int mpeg_version, y4m_ratio_t sampleaspect,
310 int frame_width, int frame_height)
311 {
312 if (Y4M_RATIO_EQL(sampleaspect, y4m_sar_UNKNOWN))
313 {
314 return 0;
315 }
316 switch (mpeg_version) {
317 case 1:
318 if (Y4M_RATIO_EQL(sampleaspect, y4m_sar_SQUARE))
319 {
320 return 1;
321 }
322 else if (Y4M_RATIO_EQL(sampleaspect, y4m_sar_NTSC_CCIR601))
323 {
324 return 12;
325 }
326 else if (Y4M_RATIO_EQL(sampleaspect, y4m_sar_NTSC_16_9))
327 {
328 return 6;
329 }
330 else if (Y4M_RATIO_EQL(sampleaspect, y4m_sar_PAL_CCIR601))
331 {
332 return 8;
333 }
334 else if (Y4M_RATIO_EQL(sampleaspect, y4m_sar_PAL_16_9))
335 {
336 return 3;
337 }
338 return 0;
339 break;
340 case 2:
341 if (Y4M_RATIO_EQL(sampleaspect, y4m_sar_SQUARE))
342 {
343 return 1; /* '1' means square *pixels* in MPEG-2; go figure. */
344 }
345 else
346 {
347 int i;
348 double true_far; /* true frame aspect ratio */
349 true_far =
350 (double)(sampleaspect.n * frame_width) /
351 (double)(sampleaspect.d * frame_height);
352 /* start at '2'... */
353 for (i = 2; i < (int)(mpeg_num_aspect_ratios[mpeg_version-1]); i++)
354 {
355 double ratio =
356 true_far / Y4M_RATIO_DBL(mpeg_aspect_ratios[mpeg_version-1][i]);
357 if ( (ratio > (1.0 - GUESS_ASPECT_TOLERANCE)) &&
358 (ratio < (1.0 + GUESS_ASPECT_TOLERANCE)) )
359 return i;
360 }
361 return 0;
362 }
363 break;
364 default:
365 return 0;
366 break;
367 }
368 }
369
370
371
372
373 /*
374 * Guess the true sample aspect ratio of a video stream,
375 * given the MPEG aspect ratio code and the actual frame size
376 * (and the MPEG version, 1 or 2).
377 *
378 * Returns y4m_sar_UNKNOWN if it has no good guess.
379 *
380 */
381 y4m_ratio_t
mpeg_guess_sample_aspect_ratio(int mpeg_version,mpeg_aspect_code_t code,int frame_width,int frame_height)382 mpeg_guess_sample_aspect_ratio(int mpeg_version,
383 mpeg_aspect_code_t code,
384 int frame_width, int frame_height)
385 {
386 switch (mpeg_version)
387 {
388 case 1:
389 /* MPEG-1 codes turn into SAR's, just not quite the right ones.
390 For the common/known values, we provide the ratio used in practice,
391 otherwise say we don't know.*/
392 switch (code)
393 {
394 case 1: return y4m_sar_SQUARE; break;
395 case 3: return y4m_sar_PAL_16_9; break;
396 case 6: return y4m_sar_NTSC_16_9; break;
397 case 8: return y4m_sar_PAL_CCIR601; break;
398 case 12: return y4m_sar_NTSC_CCIR601; break;
399 default:
400 return y4m_sar_UNKNOWN; break;
401 }
402 break;
403 case 2:
404 /* MPEG-2 codes turn into Display Aspect Ratios, though not exactly the
405 DAR's used in practice. For common/standard frame sizes, we provide
406 the original SAR; otherwise, we say we don't know. */
407 if (code == 1)
408 {
409 return y4m_sar_SQUARE; /* '1' means square *pixels* in MPEG-2 */
410 }
411 else if ((code >= 2) && (code <= 4))
412 {
413 return y4m_guess_sar(frame_width, frame_height,
414 mpeg2_aspect_ratios[code]);
415 }
416 else
417 {
418 return y4m_sar_UNKNOWN;
419 }
420 break;
421 default:
422 return y4m_sar_UNKNOWN;
423 break;
424 }
425 }
426
427
428
429
430
431 /*
432 * Look-up MPEG explanatory definition string for frame rate code
433 *
434 */
435
436
437 const char *
mpeg_framerate_code_definition(mpeg_framerate_code_t code)438 mpeg_framerate_code_definition( mpeg_framerate_code_t code )
439 {
440 if( code == 0 || code >= mpeg_num_framerates )
441 return "UNDEFINED: illegal/reserved frame-rate ratio code";
442
443 return framerate_definitions[code];
444 }
445
446 /*
447 * Look-up MPEG explanatory definition string aspect ratio code for an
448 * aspect ratio code
449 *
450 */
451
452 const char *
mpeg_aspect_code_definition(int mpeg_version,mpeg_aspect_code_t code)453 mpeg_aspect_code_definition( int mpeg_version, mpeg_aspect_code_t code )
454 {
455 if( mpeg_version < 1 || mpeg_version > 2 )
456 return "UNDEFINED: illegal MPEG version";
457
458 if( code < 1 || code >= mpeg_num_aspect_ratios[mpeg_version-1] )
459 return "UNDEFINED: illegal aspect ratio code";
460
461 return aspect_ratio_definitions[mpeg_version-1][code];
462 }
463
464
465 /*
466 * Look-up explanatory definition of interlace field order code
467 *
468 */
469
470 const char *
mpeg_interlace_code_definition(int yuv4m_interlace_code)471 mpeg_interlace_code_definition( int yuv4m_interlace_code )
472 {
473 const char *def;
474 switch( yuv4m_interlace_code )
475 {
476 case Y4M_UNKNOWN :
477 def = "unknown";
478 break;
479 case Y4M_ILACE_NONE :
480 def = "none/progressive";
481 break;
482 case Y4M_ILACE_TOP_FIRST :
483 def = "top-field-first";
484 break;
485 case Y4M_ILACE_BOTTOM_FIRST :
486 def = "bottom-field-first";
487 break;
488 default :
489 def = "UNDEFINED: illegal video interlacing type-code!";
490 break;
491 }
492 return def;
493 }
494
495 /*
496 * Look-up explanatory definition of mjepgtools preset format code
497 *
498 */
mpeg_format_code_defintion(int format_code)499 const char *mpeg_format_code_defintion( int format_code )
500 {
501 if(format_code >= MPEG_FORMAT_FIRST && format_code <= MPEG_FORMAT_LAST )
502 return mjpegtools_format_code_definitions[format_code];
503 else
504 return "UNDEFINED: illegal format code!";
505 };
506
507 /*
508 * Local variables:
509 * c-file-style: "stroustrup"
510 * tab-width: 4
511 * indent-tabs-mode: nil
512 * End:
513 */
514