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