1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 #include <schroedinger/schro.h>
6 #include <string.h>
7 #include <stdlib.h>
8
9
10 /*
11 * schro_video_format_validate:
12 * @format: pointer to a SchroVideoFormat structure
13 *
14 * Checks the video format structure pointed to by @format for
15 * inconsistencies.
16 *
17 * Returns: TRUE if the contents of @format is valid
18 */
19 int
schro_video_format_validate(SchroVideoFormat * format)20 schro_video_format_validate (SchroVideoFormat * format)
21 {
22 int fix_clean_area = 0;
23
24 if (format->aspect_ratio_numerator == 0) {
25 SCHRO_ERROR ("aspect_ratio_numerator is 0");
26 format->aspect_ratio_numerator = 1;
27 }
28 if (format->aspect_ratio_denominator == 0) {
29 SCHRO_ERROR ("aspect_ratio_denominator is 0");
30 format->aspect_ratio_denominator = 1;
31 }
32
33 if (format->clean_width + format->left_offset > format->width) {
34 SCHRO_ERROR
35 ("10.3.7: horizontal clean area is not legal (clean_width + left_offset > width)");
36 fix_clean_area = 1;
37 }
38 if (format->clean_height + format->top_offset > format->height) {
39 SCHRO_ERROR
40 ("10.3.7: vertical clean area is not legal (clean_height + top_offset > height)");
41 fix_clean_area = 1;
42 }
43 if (fix_clean_area) {
44 SCHRO_ERROR ("resetting clean area to frame size");
45 format->clean_width = format->width;
46 format->clean_height = format->height;
47 format->left_offset = format->top_offset = 0;
48 }
49
50 if (schro_video_format_get_bit_depth (format) != 8) {
51 SCHRO_WARNING ("video bit depth != 8");
52 return 0;
53 }
54
55 return 1;
56 }
57
58 #ifdef unused
59 int
schro_video_format_compare_new_sequence(SchroVideoFormat * a,SchroVideoFormat * b)60 schro_video_format_compare_new_sequence (SchroVideoFormat * a,
61 SchroVideoFormat * b)
62 {
63 if (a->index != b->index ||
64 a->width != b->width ||
65 a->height != b->height ||
66 a->chroma_format != b->chroma_format ||
67 a->interlaced != b->interlaced ||
68 a->top_field_first != b->top_field_first ||
69 a->frame_rate_numerator != b->frame_rate_numerator ||
70 a->frame_rate_denominator != b->frame_rate_denominator ||
71 a->aspect_ratio_numerator != b->aspect_ratio_numerator ||
72 a->aspect_ratio_denominator != b->aspect_ratio_denominator ||
73 a->clean_width != b->clean_width ||
74 a->clean_height != b->clean_height ||
75 a->left_offset != b->left_offset ||
76 a->top_offset != b->top_offset ||
77 a->luma_offset != b->luma_offset ||
78 a->luma_excursion != b->luma_excursion ||
79 a->chroma_offset != b->chroma_offset ||
80 a->chroma_excursion != b->chroma_excursion ||
81 a->colour_primaries != b->colour_primaries ||
82 a->colour_matrix != b->colour_matrix ||
83 a->transfer_function != b->transfer_function) {
84 return FALSE;
85 }
86 return TRUE;
87 }
88 #endif
89
90 #ifdef unused
91 int
schro_video_format_compare(SchroVideoFormat * a,SchroVideoFormat * b)92 schro_video_format_compare (SchroVideoFormat * a, SchroVideoFormat * b)
93 {
94 if (!schro_video_format_compare_new_sequence (a, b) ||
95 a->interlaced_coding != b->interlaced_coding) {
96 return FALSE;
97 }
98 return TRUE;
99 }
100 #endif
101
102 int
schro_video_format_get_bit_depth(SchroVideoFormat * format)103 schro_video_format_get_bit_depth (SchroVideoFormat * format)
104 {
105 int max;
106 int i;
107
108 max = MAX (format->chroma_excursion, format->luma_excursion);
109
110 for (i = 0; i < 32; i++) {
111 if (max < (1 << i))
112 return i;
113 }
114 return 0;
115 }
116
117 static SchroVideoFormat schro_video_formats[] = {
118 {0, /* custom */
119 640, 480, SCHRO_CHROMA_420,
120 FALSE, FALSE,
121 24000, 1001, 1, 1,
122 640, 480, 0, 0,
123 0, 255, 128, 255,
124 0, 0, 0},
125 {1, /* QSIF525 */
126 176, 120, SCHRO_CHROMA_420,
127 FALSE, FALSE,
128 15000, 1001, 10, 11,
129 176, 120, 0, 0,
130 0, 255, 128, 255,
131 1, 1, 0},
132 {2, /* QCIF */
133 176, 144, SCHRO_CHROMA_420,
134 FALSE, TRUE,
135 25, 2, 12, 11,
136 176, 144, 0, 0,
137 0, 255, 128, 255,
138 2, 1, 0},
139 {3, /* SIF525 */
140 352, 240, SCHRO_CHROMA_420,
141 FALSE, FALSE,
142 15000, 1001, 10, 11,
143 352, 240, 0, 0,
144 0, 255, 128, 255,
145 1, 1, 0},
146 {4, /* CIF */
147 352, 288, SCHRO_CHROMA_420,
148 FALSE, TRUE,
149 25, 2, 12, 11,
150 352, 288, 0, 0,
151 0, 255, 128, 255,
152 2, 1, 0},
153 {5, /* 4SIF525 */
154 704, 480, SCHRO_CHROMA_420,
155 FALSE, FALSE,
156 15000, 1001, 10, 11,
157 704, 480, 0, 0,
158 0, 255, 128, 255,
159 1, 1, 0},
160 {6, /* 4CIF */
161 704, 576, SCHRO_CHROMA_420,
162 FALSE, TRUE,
163 25, 2, 12, 11,
164 704, 576, 0, 0,
165 0, 255, 128, 255,
166 2, 1, 0},
167 {7, /* SD480I-60 */
168 720, 480, SCHRO_CHROMA_422,
169 TRUE, FALSE,
170 30000, 1001, 10, 11,
171 704, 480, 8, 0,
172 64, 876, 512, 896,
173 1, 1, 0},
174 {8, /* SD576I-50 */
175 720, 576, SCHRO_CHROMA_422,
176 TRUE, TRUE,
177 25, 1, 12, 11,
178 704, 576, 8, 0,
179 64, 876, 512, 896,
180 2, 1, 0},
181 {9, /* HD720P-60 */
182 1280, 720, SCHRO_CHROMA_422,
183 FALSE, TRUE,
184 60000, 1001, 1, 1,
185 1280, 720, 0, 0,
186 64, 876, 512, 896,
187 0, 0, 0},
188 {10, /* HD720P-50 */
189 1280, 720, SCHRO_CHROMA_422,
190 FALSE, TRUE,
191 50, 1, 1, 1,
192 1280, 720, 0, 0,
193 64, 876, 512, 896,
194 0, 0, 0},
195 {11, /* HD1080I-60 */
196 1920, 1080, SCHRO_CHROMA_422,
197 TRUE, TRUE,
198 30000, 1001, 1, 1,
199 1920, 1080, 0, 0,
200 64, 876, 512, 896,
201 0, 0, 0},
202 {12, /* HD1080I-50 */
203 1920, 1080, SCHRO_CHROMA_422,
204 TRUE, TRUE,
205 25, 1, 1, 1,
206 1920, 1080, 0, 0,
207 64, 876, 512, 896,
208 0, 0, 0},
209 {13, /* HD1080P-60 */
210 1920, 1080, SCHRO_CHROMA_422,
211 FALSE, TRUE,
212 60000, 1001, 1, 1,
213 1920, 1080, 0, 0,
214 64, 876, 512, 896,
215 0, 0, 0},
216 {14, /* HD1080P-50 */
217 1920, 1080, SCHRO_CHROMA_422,
218 FALSE, TRUE,
219 50, 1, 1, 1,
220 1920, 1080, 0, 0,
221 64, 876, 512, 896,
222 0, 0, 0},
223 {15, /* DC2K */
224 2048, 1080, SCHRO_CHROMA_444,
225 FALSE, TRUE,
226 24, 1, 1, 1,
227 2048, 1080, 0, 0,
228 256, 3504, 2048, 3584,
229 3, 0, 0},
230 {16, /* DC4K */
231 4096, 2160, SCHRO_CHROMA_444,
232 FALSE, TRUE,
233 24, 1, 1, 1,
234 2048, 1536, 0, 0,
235 256, 3504, 2048, 3584,
236 3, 0, 0},
237 {17, /* UHDTV 4K-60 */
238 3840, 2160, SCHRO_CHROMA_422,
239 FALSE, TRUE,
240 60000, 1001, 1, 1,
241 3840, 2160, 0, 0,
242 64, 876, 512, 896,
243 0, 0, 0},
244 {18, /* UHDTV 4K-50 */
245 3840, 2160, SCHRO_CHROMA_422,
246 FALSE, TRUE,
247 50, 1, 1, 1,
248 3840, 2160, 0, 0,
249 64, 876, 512, 896,
250 0, 0, 0},
251 {19, /* UHDTV 8K-60 */
252 7680, 4320, SCHRO_CHROMA_422,
253 FALSE, TRUE,
254 60000, 1001, 1, 1,
255 7680, 4320, 0, 0,
256 64, 876, 512, 896,
257 0, 0, 0},
258 {20, /* UHDTV 8K-50 */
259 7680, 4320, SCHRO_CHROMA_422,
260 FALSE, TRUE,
261 50, 1, 1, 1,
262 7680, 4320, 0, 0,
263 64, 876, 512, 896,
264 0, 0, 0},
265 };
266
267 /**
268 * schro_video_format_set_std_video_format:
269 * @format:
270 * @index:
271 *
272 * Initializes the video format structure pointed to by @format to
273 * the standard Dirac video formats specified by @index.
274 */
275 void
schro_video_format_set_std_video_format(SchroVideoFormat * format,SchroVideoFormatEnum index)276 schro_video_format_set_std_video_format (SchroVideoFormat * format,
277 SchroVideoFormatEnum index)
278 {
279 if (index < 0 || index >= ARRAY_SIZE (schro_video_formats)) {
280 SCHRO_ERROR ("illegal video format index");
281 return;
282 }
283
284 memcpy (format, schro_video_formats + index, sizeof (SchroVideoFormat));
285 }
286
287 static int
schro_video_format_get_video_format_metric(SchroVideoFormat * format,int i)288 schro_video_format_get_video_format_metric (SchroVideoFormat * format, int i)
289 {
290 SchroVideoFormat *std_format;
291 int metric = 0;
292
293 std_format = schro_video_formats + i;
294
295 /* this is really important because it can't be overrided */
296 if (format->interlaced &&
297 format->top_field_first == std_format->top_field_first) {
298 metric |= 0x8000;
299 }
300
301 metric += schro_pack_estimate_uint (i);
302
303 if (std_format->width == format->width &&
304 std_format->height == format->height) {
305 metric++;
306 } else {
307 metric++;
308 metric += schro_pack_estimate_uint (format->width);
309 metric += schro_pack_estimate_uint (format->height);
310 }
311
312 if (std_format->chroma_format == format->chroma_format) {
313 metric++;
314 } else {
315 metric++;
316 metric += schro_pack_estimate_uint (format->chroma_format);
317 }
318
319 /* scan format */
320 if (std_format->interlaced == format->interlaced) {
321 metric++;
322 } else {
323 metric++;
324 metric += schro_pack_estimate_uint (format->interlaced);
325 }
326
327 /* frame rate */
328 if (std_format->frame_rate_numerator == format->frame_rate_numerator &&
329 std_format->frame_rate_denominator == format->frame_rate_denominator) {
330 metric++;
331 } else {
332 metric++;
333 i = schro_video_format_get_std_frame_rate (format);
334 metric += schro_pack_estimate_uint (i);
335 if (i == 0) {
336 metric += schro_pack_estimate_uint (format->frame_rate_numerator);
337 metric += schro_pack_estimate_uint (format->frame_rate_denominator);
338 }
339 }
340
341 /* pixel aspect ratio */
342 if (std_format->aspect_ratio_numerator == format->aspect_ratio_numerator &&
343 std_format->aspect_ratio_denominator ==
344 format->aspect_ratio_denominator) {
345 metric++;
346 } else {
347 metric++;
348 i = schro_video_format_get_std_aspect_ratio (format);
349 metric += schro_pack_estimate_uint (i);
350 if (i == 0) {
351 metric += schro_pack_estimate_uint (format->aspect_ratio_numerator);
352 metric += schro_pack_estimate_uint (format->aspect_ratio_denominator);
353 }
354 }
355
356 /* clean area */
357 if (std_format->clean_width == format->clean_width &&
358 std_format->clean_height == format->clean_height &&
359 std_format->left_offset == format->left_offset &&
360 std_format->top_offset == format->top_offset) {
361 metric++;
362 } else {
363 metric++;
364 metric += schro_pack_estimate_uint (format->clean_width);
365 metric += schro_pack_estimate_uint (format->clean_height);
366 metric += schro_pack_estimate_uint (format->left_offset);
367 metric += schro_pack_estimate_uint (format->top_offset);
368 }
369
370
371 #if 0
372 if (format->left_offset == std_format->left_offset &&
373 format->top_offset == std_format->top_offset &&
374 format->clean_width == std_format->clean_width &&
375 format->clean_height == std_format->clean_height) {
376 metric |= 0x40;
377 }
378 #endif
379
380 return metric;
381 }
382
383 /**
384 * schro_video_format_get_std_video_format:
385 * @format: pointer to SchroVideoFormat structure
386 *
387 * In Dirac streams, video formats are encoded by specifying a standard
388 * format, and then modifying that to get the desired video format. This
389 * function guesses a standard format to use as a starting point for
390 * encoding the video format pointed to by @format.
391 *
392 * Returns: an index to the optimal standard format
393 */
394 SchroVideoFormatEnum
schro_video_format_get_std_video_format(SchroVideoFormat * format)395 schro_video_format_get_std_video_format (SchroVideoFormat * format)
396 {
397 int metric;
398 int max_index;
399 int max_metric;
400 int i;
401
402 max_index = 0;
403 max_metric = schro_video_format_get_video_format_metric (format, 1);
404 for (i = 1; i < ARRAY_SIZE (schro_video_formats); i++) {
405 metric = schro_video_format_get_video_format_metric (format, i);
406 if (metric > max_metric) {
407 max_index = i;
408 max_metric = metric;
409 }
410 }
411 return max_index;
412 }
413
414 typedef struct _SchroFrameRate SchroFrameRate;
415 struct _SchroFrameRate
416 {
417 int numerator;
418 int denominator;
419 };
420
421 static SchroFrameRate schro_frame_rates[] = {
422 {0, 0},
423 {24000, 1001},
424 {24, 1},
425 {25, 1},
426 {30000, 1001},
427 {30, 1},
428 {50, 1},
429 {60000, 1001},
430 {60, 1},
431 {15000, 1001},
432 {25, 2}
433 };
434
435 /**
436 * schro_video_format_set_std_frame_rate:
437 * @format:
438 * @index:
439 *
440 * Sets the frame rate of the video format structure pointed to by
441 * @format to the Dirac standard frame specified by @index.
442 */
443 void
schro_video_format_set_std_frame_rate(SchroVideoFormat * format,int index)444 schro_video_format_set_std_frame_rate (SchroVideoFormat * format, int index)
445 {
446 if (index < 1 || index >= ARRAY_SIZE (schro_frame_rates)) {
447 SCHRO_ERROR ("illegal frame rate index");
448 return;
449 }
450
451 format->frame_rate_numerator = schro_frame_rates[index].numerator;
452 format->frame_rate_denominator = schro_frame_rates[index].denominator;
453 }
454
455 /**
456 * schro_video_format_get_std_frame_rate:
457 * @format:
458 *
459 * In Dirac bitstreams, frame rates can be one of several standard
460 * frame rates, encoded as an index, or the numerator and denominator
461 * of the framerate can be encoded directly. This function looks up
462 * the frame rate contained in the video format structure @format in
463 * the list of standard frame rates. If the frame rate is a standard
464 * frame rate, the corresponding index is returned, otherwise 0 is
465 * returned.
466 *
467 * Returns: index to a standard Dirac frame rate, or 0 if the frame rate
468 * is custom.
469 */
470 int
schro_video_format_get_std_frame_rate(SchroVideoFormat * format)471 schro_video_format_get_std_frame_rate (SchroVideoFormat * format)
472 {
473 int i;
474
475 for (i = 1; i < ARRAY_SIZE (schro_frame_rates); i++) {
476 if (format->frame_rate_numerator == schro_frame_rates[i].numerator &&
477 format->frame_rate_denominator == schro_frame_rates[i].denominator) {
478 return i;
479 }
480 }
481
482 return 0;
483 }
484
485 typedef struct _SchroPixelAspectRatio SchroPixelAspectRatio;
486 struct _SchroPixelAspectRatio
487 {
488 int numerator;
489 int denominator;
490 };
491
492 static const SchroPixelAspectRatio schro_aspect_ratios[] = {
493 {0, 0},
494 {1, 1},
495 {10, 11},
496 {12, 11},
497 {40, 33},
498 {16, 11},
499 {4, 3}
500 };
501
502 /*
503 * schro_video_format_set_std_aspect_ratio:
504 * @format: pointer to a SchroVideoFormat structure
505 * @index: index to a standard aspect ratio
506 *
507 * Sets the pixel aspect ratio of the video format structure pointed to
508 * by @format to the standard pixel aspect ratio indicated by @index.
509 */
510 void
schro_video_format_set_std_aspect_ratio(SchroVideoFormat * format,int index)511 schro_video_format_set_std_aspect_ratio (SchroVideoFormat * format, int index)
512 {
513 if (index < 1 || index >= ARRAY_SIZE (schro_aspect_ratios)) {
514 SCHRO_ERROR ("illegal pixel aspect ratio index");
515 return;
516 }
517
518 format->aspect_ratio_numerator = schro_aspect_ratios[index].numerator;
519 format->aspect_ratio_denominator = schro_aspect_ratios[index].denominator;
520
521 }
522
523 /*
524 * schro_video_format_get_std_aspect_ratio:
525 * @format: pointer to a SchroVideoFormat structure
526 *
527 * In Dirac bitstreams, pixel aspect ratios can be one of several standard
528 * pixel aspect ratios, encoded as an index, or the numerator and denominator
529 * of the pixel aspect ratio can be encoded directly. This function looks up
530 * the pixel aspect ratio contained in the video format structure @format in
531 * the list of standard pixel aspect ratios. If the pixel aspect ratio is
532 * a standard pixel aspect ratio, the corresponding index is returned,
533 * otherwise 0 is returned.
534 *
535 * Returns: index to standard pixel aspect ratio, or 0 if there is no
536 * corresponding standard pixel aspect ratio.
537 */
538 int
schro_video_format_get_std_aspect_ratio(SchroVideoFormat * format)539 schro_video_format_get_std_aspect_ratio (SchroVideoFormat * format)
540 {
541 int i;
542
543 for (i = 1; i < ARRAY_SIZE (schro_aspect_ratios); i++) {
544 if (format->aspect_ratio_numerator ==
545 schro_aspect_ratios[i].numerator &&
546 format->aspect_ratio_denominator ==
547 schro_aspect_ratios[i].denominator) {
548 return i;
549 }
550 }
551
552 return 0;
553 }
554
555 typedef struct _SchroSignalRangeStruct SchroSignalRangeStruct;
556 struct _SchroSignalRangeStruct
557 {
558 int luma_offset;
559 int luma_excursion;
560 int chroma_offset;
561 int chroma_excursion;
562 };
563
564 static const SchroSignalRangeStruct schro_signal_ranges[] = {
565 {0, 0, 0, 0},
566 {0, 255, 128, 255},
567 {16, 219, 128, 224},
568 {64, 876, 512, 896},
569 {256, 3504, 2048, 3584}
570 };
571
572 /**
573 * schro_video_format_set_std_signal_range:
574 * @format:
575 * @index:
576 *
577 * Sets the signal range of the video format structure to one of the
578 * standard values indicated by @index.
579 */
580 void
schro_video_format_set_std_signal_range(SchroVideoFormat * format,SchroSignalRange i)581 schro_video_format_set_std_signal_range (SchroVideoFormat * format,
582 SchroSignalRange i)
583 {
584 if (i < 1 || i >= ARRAY_SIZE (schro_signal_ranges)) {
585 SCHRO_ERROR ("illegal signal range index");
586 return;
587 }
588
589 format->luma_offset = schro_signal_ranges[i].luma_offset;
590 format->luma_excursion = schro_signal_ranges[i].luma_excursion;
591 format->chroma_offset = schro_signal_ranges[i].chroma_offset;
592 format->chroma_excursion = schro_signal_ranges[i].chroma_excursion;
593 }
594
595 /**
596 * schro_video_format_get_std_signal_range:
597 * @format: pointer to SchroVideoFormat structure
598 *
599 * In Dirac bitstreams, signal ranges can be one of several standard
600 * signal ranges, encoded as an index, or the extents of the signal
601 * range can be encoded directly. This function looks up
602 * the signal range contained in the video format structure @format in
603 * the list of standard signal ranges. If the signal range is
604 * a standard signal range, the corresponding index is returned,
605 * otherwise 0 is returned.
606 *
607 * Returns: index to standard signal range, or 0 if there is no
608 * corresponding standard signal range.
609 */
610 SchroSignalRange
schro_video_format_get_std_signal_range(SchroVideoFormat * format)611 schro_video_format_get_std_signal_range (SchroVideoFormat * format)
612 {
613 int i;
614
615 for (i = 1; i < ARRAY_SIZE (schro_signal_ranges); i++) {
616 if (format->luma_offset == schro_signal_ranges[i].luma_offset &&
617 format->luma_excursion == schro_signal_ranges[i].luma_excursion &&
618 format->chroma_offset == schro_signal_ranges[i].chroma_offset &&
619 format->chroma_excursion == schro_signal_ranges[i].chroma_excursion) {
620 return i;
621 }
622 }
623
624 return 0;
625
626 }
627
628 typedef struct _SchroColourSpecStruct SchroColourSpecStruct;
629 struct _SchroColourSpecStruct
630 {
631 int colour_primaries;
632 int colour_matrix;
633 int transfer_function;
634 };
635
636 static const SchroColourSpecStruct schro_colour_specs[] = {
637 { /* Custom */
638 SCHRO_COLOUR_PRIMARY_HDTV,
639 SCHRO_COLOUR_MATRIX_HDTV,
640 SCHRO_TRANSFER_CHAR_TV_GAMMA},
641 { /* SDTV 525 */
642 SCHRO_COLOUR_PRIMARY_SDTV_525,
643 SCHRO_COLOUR_MATRIX_SDTV,
644 SCHRO_TRANSFER_CHAR_TV_GAMMA},
645 { /* SDTV 625 */
646 SCHRO_COLOUR_PRIMARY_SDTV_625,
647 SCHRO_COLOUR_MATRIX_SDTV,
648 SCHRO_TRANSFER_CHAR_TV_GAMMA},
649 { /* HDTV */
650 SCHRO_COLOUR_PRIMARY_HDTV,
651 SCHRO_COLOUR_MATRIX_HDTV,
652 SCHRO_TRANSFER_CHAR_TV_GAMMA},
653 { /* Cinema */
654 SCHRO_COLOUR_PRIMARY_CINEMA,
655 SCHRO_COLOUR_MATRIX_HDTV,
656 SCHRO_TRANSFER_CHAR_TV_GAMMA}
657 };
658
659 /**
660 * schro_video_format_set_std_colour_spec:
661 * @format: pointer to SchroVideoFormat structure
662 * @index: index to standard colour specification
663 *
664 * Sets the colour specification of the video format structure to one of the
665 * standard values indicated by @index.
666 */
667 void
schro_video_format_set_std_colour_spec(SchroVideoFormat * format,SchroColourSpec i)668 schro_video_format_set_std_colour_spec (SchroVideoFormat * format,
669 SchroColourSpec i)
670 {
671 if (i < 0 || i >= ARRAY_SIZE (schro_colour_specs)) {
672 SCHRO_ERROR ("illegal signal range index");
673 return;
674 }
675
676 format->colour_primaries = schro_colour_specs[i].colour_primaries;
677 format->colour_matrix = schro_colour_specs[i].colour_matrix;
678 format->transfer_function = schro_colour_specs[i].transfer_function;
679 }
680
681 /**
682 * schro_video_format_get_std_colour_spec:
683 * @format: pointer to SchroVideoFormat structure
684 *
685 * In Dirac bitstreams, colour specifications can be one of several standard
686 * colour specifications, encoded as an index, or the individual parts of
687 * the colour specication can be encoded. This function looks up
688 * the colour specification contained in the video format structure @format in
689 * the list of standard colour specifications. If the colour specification is
690 * a standard colour specification, the corresponding index is returned,
691 * otherwise 0 is returned.
692 *
693 * Returns: index to standard colour specification, or 0 if there is no
694 * corresponding standard colour specification.
695 */
696 SchroColourSpec
schro_video_format_get_std_colour_spec(SchroVideoFormat * format)697 schro_video_format_get_std_colour_spec (SchroVideoFormat * format)
698 {
699 int i;
700
701 for (i = 1; i < ARRAY_SIZE (schro_colour_specs); i++) {
702 if (format->colour_primaries == schro_colour_specs[i].colour_primaries &&
703 format->colour_matrix == schro_colour_specs[i].colour_matrix &&
704 format->transfer_function == schro_colour_specs[i].transfer_function) {
705 return i;
706 }
707 }
708
709 return 0;
710 }
711
712 /**
713 * schro_video_format_get_picture_height:
714 * @format: pointer to SchroVideoFormat structure
715 *
716 * Returns the height of coded pictures in the Dirac stream. For
717 * streams encoded with interlaced_coding enabled, this will be the
718 * field height, or half of the video height.
719 */
720 int
schro_video_format_get_picture_height(SchroVideoFormat * format)721 schro_video_format_get_picture_height (SchroVideoFormat * format)
722 {
723 if (format->interlaced_coding) {
724 return ROUND_UP_SHIFT (format->height, 1);
725 }
726 return format->height;
727 }
728
729 #ifdef unused
730 int
schro_video_format_get_chroma_width(SchroVideoFormat * format)731 schro_video_format_get_chroma_width (SchroVideoFormat * format)
732 {
733 return ROUND_UP_SHIFT (format->width,
734 SCHRO_CHROMA_FORMAT_H_SHIFT (format->chroma_format));
735 }
736 #endif
737
738 #ifdef unused
739 int
schro_video_format_get_chroma_height(SchroVideoFormat * format)740 schro_video_format_get_chroma_height (SchroVideoFormat * format)
741 {
742 return ROUND_UP_SHIFT (format->height,
743 SCHRO_CHROMA_FORMAT_V_SHIFT (format->chroma_format));
744 }
745 #endif
746
747 void
schro_video_format_get_picture_luma_size(SchroVideoFormat * format,int * width,int * height)748 schro_video_format_get_picture_luma_size (SchroVideoFormat * format,
749 int *width, int *height)
750 {
751 *width = format->width;
752 *height = ROUND_UP_SHIFT (format->height, format->interlaced_coding);
753 }
754
755 void
schro_video_format_get_picture_chroma_size(SchroVideoFormat * format,int * width,int * height)756 schro_video_format_get_picture_chroma_size (SchroVideoFormat * format,
757 int *width, int *height)
758 {
759 *width = ROUND_UP_SHIFT (format->width,
760 SCHRO_CHROMA_FORMAT_H_SHIFT (format->chroma_format));
761 *height = ROUND_UP_SHIFT (format->height,
762 SCHRO_CHROMA_FORMAT_V_SHIFT (format->chroma_format) +
763 format->interlaced_coding);
764 }
765
766 void
schro_video_format_get_iwt_alloc_size(SchroVideoFormat * format,int * width,int * height,int transform_depth)767 schro_video_format_get_iwt_alloc_size (SchroVideoFormat * format,
768 int *width, int *height, int transform_depth)
769 {
770 int picture_chroma_width;
771 int picture_chroma_height;
772
773 schro_video_format_get_picture_chroma_size (format, &picture_chroma_width,
774 &picture_chroma_height);
775
776 picture_chroma_width = ROUND_UP_POW2 (picture_chroma_width, transform_depth);
777 picture_chroma_height = ROUND_UP_POW2 (picture_chroma_height,
778 transform_depth);
779
780 *width = picture_chroma_width <<
781 SCHRO_CHROMA_FORMAT_H_SHIFT (format->chroma_format);
782 *height = picture_chroma_height <<
783 SCHRO_CHROMA_FORMAT_V_SHIFT (format->chroma_format);
784 }
785
786 schro_bool
schro_video_format_check_MP_DL(SchroVideoFormat * format)787 schro_video_format_check_MP_DL (SchroVideoFormat * format)
788 {
789 SchroVideoFormat base_format;
790
791 if (format->index < 1 || format->index > 20) {
792 return FALSE;
793 }
794
795 schro_video_format_set_std_video_format (&base_format, format->index);
796
797 if (format->width > base_format.width || format->height > base_format.height) {
798 return FALSE;
799 }
800
801 if (format->frame_rate_numerator != base_format.frame_rate_numerator ||
802 format->frame_rate_denominator != base_format.frame_rate_denominator) {
803 return FALSE;
804 }
805
806 if (format->clean_width != base_format.clean_width ||
807 format->clean_height != base_format.clean_height ||
808 format->left_offset != base_format.left_offset ||
809 format->top_offset != base_format.top_offset) {
810 return FALSE;
811 }
812
813 if (schro_video_format_get_std_signal_range (format) != 2) {
814 return FALSE;
815 }
816
817 if (format->colour_primaries != base_format.colour_primaries ||
818 format->colour_matrix != base_format.colour_matrix ||
819 format->transfer_function != base_format.transfer_function) {
820 return FALSE;
821 }
822
823 return TRUE;
824 }
825
826 schro_bool
schro_video_format_check_VC2_DL(SchroVideoFormat * format)827 schro_video_format_check_VC2_DL (SchroVideoFormat * format)
828 {
829 SchroVideoFormat base_format;
830
831 if (format->index < 1 || format->index > 20) {
832 return FALSE;
833 }
834
835 schro_video_format_set_std_video_format (&base_format, format->index);
836
837 if (memcmp (&base_format, format, sizeof (SchroVideoFormat)) != 0) {
838 return FALSE;
839 }
840
841 return TRUE;
842 }
843