• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include "dirac_parse.h"
3 #include <string.h>
4 
5 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
6 
7 typedef struct _Unpack Unpack;
8 
9 struct _Unpack
10 {
11   unsigned char *data;
12   int n_bits_left;
13   int index;
14   int guard_bit;
15 };
16 
17 static void schro_unpack_init_with_data (Unpack * unpack, unsigned char *data,
18     int n_bytes, unsigned int guard_bit);
19 
20 static unsigned int schro_unpack_decode_bit (Unpack * unpack);
21 static unsigned int schro_unpack_decode_uint (Unpack * unpack);
22 
23 
24 static void schro_video_format_set_std_video_format (DiracSequenceHeader *
25     format, int index);
26 static void schro_video_format_set_std_frame_rate (DiracSequenceHeader * format,
27     int index);
28 static void schro_video_format_set_std_aspect_ratio (DiracSequenceHeader *
29     format, int index);
30 static void schro_video_format_set_std_signal_range (DiracSequenceHeader *
31     format, int index);
32 static void schro_video_format_set_std_colour_spec (DiracSequenceHeader *
33     format, int index);
34 
35 
36 
37 
38 int
gst_dirac_sequence_header_parse(DiracSequenceHeader * header,unsigned char * data,int n_bytes)39 gst_dirac_sequence_header_parse (DiracSequenceHeader * header,
40     unsigned char *data, int n_bytes)
41 {
42   int bit;
43   int index;
44   Unpack _unpack;
45   Unpack *unpack = &_unpack;
46   int major_version;
47   int minor_version;
48   int profile;
49   int level;
50 
51   memset (header, 0, sizeof (*header));
52 
53   schro_unpack_init_with_data (unpack, data, n_bytes, 1);
54 
55   /* parse parameters */
56   major_version = schro_unpack_decode_uint (unpack);
57   minor_version = schro_unpack_decode_uint (unpack);
58   profile = schro_unpack_decode_uint (unpack);
59   level = schro_unpack_decode_uint (unpack);
60 
61   /* base video header */
62   index = schro_unpack_decode_uint (unpack);
63   schro_video_format_set_std_video_format (header, index);
64 
65   header->major_version = major_version;
66   header->minor_version = minor_version;
67   header->profile = profile;
68   header->level = level;
69 
70   /* source parameters */
71   /* frame dimensions */
72   bit = schro_unpack_decode_bit (unpack);
73   if (bit) {
74     header->width = schro_unpack_decode_uint (unpack);
75     header->height = schro_unpack_decode_uint (unpack);
76   }
77 
78   /* chroma header */
79   bit = schro_unpack_decode_bit (unpack);
80   if (bit) {
81     header->chroma_format = schro_unpack_decode_uint (unpack);
82   }
83 
84   /* scan header */
85   bit = schro_unpack_decode_bit (unpack);
86   if (bit) {
87     header->interlaced = schro_unpack_decode_uint (unpack);
88   }
89 
90   /* frame rate */
91   bit = schro_unpack_decode_bit (unpack);
92   if (bit) {
93     index = schro_unpack_decode_uint (unpack);
94     if (index == 0) {
95       header->frame_rate_numerator = schro_unpack_decode_uint (unpack);
96       header->frame_rate_denominator = schro_unpack_decode_uint (unpack);
97     } else {
98       schro_video_format_set_std_frame_rate (header, index);
99     }
100   }
101 
102   /* aspect ratio */
103   bit = schro_unpack_decode_bit (unpack);
104   if (bit) {
105     index = schro_unpack_decode_uint (unpack);
106     if (index == 0) {
107       header->aspect_ratio_numerator = schro_unpack_decode_uint (unpack);
108       header->aspect_ratio_denominator = schro_unpack_decode_uint (unpack);
109     } else {
110       schro_video_format_set_std_aspect_ratio (header, index);
111     }
112   }
113 
114   /* clean area */
115   bit = schro_unpack_decode_bit (unpack);
116   if (bit) {
117     header->clean_width = schro_unpack_decode_uint (unpack);
118     header->clean_height = schro_unpack_decode_uint (unpack);
119     header->left_offset = schro_unpack_decode_uint (unpack);
120     header->top_offset = schro_unpack_decode_uint (unpack);
121   }
122 
123   /* signal range */
124   bit = schro_unpack_decode_bit (unpack);
125   if (bit) {
126     index = schro_unpack_decode_uint (unpack);
127     if (index == 0) {
128       header->luma_offset = schro_unpack_decode_uint (unpack);
129       header->luma_excursion = schro_unpack_decode_uint (unpack);
130       header->chroma_offset = schro_unpack_decode_uint (unpack);
131       header->chroma_excursion = schro_unpack_decode_uint (unpack);
132     } else {
133       schro_video_format_set_std_signal_range (header, index);
134     }
135   }
136 
137   /* colour spec */
138   bit = schro_unpack_decode_bit (unpack);
139   if (bit) {
140     index = schro_unpack_decode_uint (unpack);
141     schro_video_format_set_std_colour_spec (header, index);
142     if (index == 0) {
143       /* colour primaries */
144       bit = schro_unpack_decode_bit (unpack);
145       if (bit) {
146         header->colour_primaries = schro_unpack_decode_uint (unpack);
147       }
148       /* colour matrix */
149       bit = schro_unpack_decode_bit (unpack);
150       if (bit) {
151         header->colour_matrix = schro_unpack_decode_uint (unpack);
152       }
153       /* transfer function */
154       bit = schro_unpack_decode_bit (unpack);
155       if (bit) {
156         header->transfer_function = schro_unpack_decode_uint (unpack);
157       }
158     }
159   }
160 
161   header->interlaced_coding = schro_unpack_decode_uint (unpack);
162 
163   return 1;
164 }
165 
166 /* standard stuff */
167 
168 static const DiracSequenceHeader schro_video_formats[] = {
169   {0, 0, 0, 0,
170         0,                      /* custom */
171         640, 480, SCHRO_CHROMA_420,
172         FALSE, FALSE,
173         24000, 1001, 1, 1,
174         640, 480, 0, 0,
175         0, 255, 128, 255,
176       0, 0, 0},
177   {0, 0, 0, 0,
178         1,                      /* QSIF525 */
179         176, 120, SCHRO_CHROMA_420,
180         FALSE, FALSE,
181         15000, 1001, 10, 11,
182         176, 120, 0, 0,
183         0, 255, 128, 255,
184       1, 1, 0},
185   {0, 0, 0, 0,
186         2,                      /* QCIF */
187         176, 144, SCHRO_CHROMA_420,
188         FALSE, TRUE,
189         25, 2, 12, 11,
190         176, 144, 0, 0,
191         0, 255, 128, 255,
192       2, 1, 0},
193   {0, 0, 0, 0,
194         3,                      /* SIF525 */
195         352, 240, SCHRO_CHROMA_420,
196         FALSE, FALSE,
197         15000, 1001, 10, 11,
198         352, 240, 0, 0,
199         0, 255, 128, 255,
200       1, 1, 0},
201   {0, 0, 0, 0,
202         4,                      /* CIF */
203         352, 288, SCHRO_CHROMA_420,
204         FALSE, TRUE,
205         25, 2, 12, 11,
206         352, 288, 0, 0,
207         0, 255, 128, 255,
208       2, 1, 0},
209   {0, 0, 0, 0,
210         5,                      /* 4SIF525 */
211         704, 480, SCHRO_CHROMA_420,
212         FALSE, FALSE,
213         15000, 1001, 10, 11,
214         704, 480, 0, 0,
215         0, 255, 128, 255,
216       1, 1, 0},
217   {0, 0, 0, 0,
218         6,                      /* 4CIF */
219         704, 576, SCHRO_CHROMA_420,
220         FALSE, TRUE,
221         25, 2, 12, 11,
222         704, 576, 0, 0,
223         0, 255, 128, 255,
224       2, 1, 0},
225   {0, 0, 0, 0,
226         7,                      /* SD480I-60 */
227         720, 480, SCHRO_CHROMA_422,
228         TRUE, FALSE,
229         30000, 1001, 10, 11,
230         704, 480, 8, 0,
231         64, 876, 512, 896,
232       1, 1, 0},
233   {0, 0, 0, 0,
234         8,                      /* SD576I-50 */
235         720, 576, SCHRO_CHROMA_422,
236         TRUE, TRUE,
237         25, 1, 12, 11,
238         704, 576, 8, 0,
239         64, 876, 512, 896,
240       2, 1, 0},
241   {0, 0, 0, 0,
242         9,                      /* HD720P-60 */
243         1280, 720, SCHRO_CHROMA_422,
244         FALSE, TRUE,
245         60000, 1001, 1, 1,
246         1280, 720, 0, 0,
247         64, 876, 512, 896,
248       0, 0, 0},
249   {0, 0, 0, 0,
250         10,                     /* HD720P-50 */
251         1280, 720, SCHRO_CHROMA_422,
252         FALSE, TRUE,
253         50, 1, 1, 1,
254         1280, 720, 0, 0,
255         64, 876, 512, 896,
256       0, 0, 0},
257   {0, 0, 0, 0,
258         11,                     /* HD1080I-60 */
259         1920, 1080, SCHRO_CHROMA_422,
260         TRUE, TRUE,
261         30000, 1001, 1, 1,
262         1920, 1080, 0, 0,
263         64, 876, 512, 896,
264       0, 0, 0},
265   {0, 0, 0, 0,
266         12,                     /* HD1080I-50 */
267         1920, 1080, SCHRO_CHROMA_422,
268         TRUE, TRUE,
269         25, 1, 1, 1,
270         1920, 1080, 0, 0,
271         64, 876, 512, 896,
272       0, 0, 0},
273   {0, 0, 0, 0,
274         13,                     /* HD1080P-60 */
275         1920, 1080, SCHRO_CHROMA_422,
276         FALSE, TRUE,
277         60000, 1001, 1, 1,
278         1920, 1080, 0, 0,
279         64, 876, 512, 896,
280       0, 0, 0},
281   {0, 0, 0, 0,
282         14,                     /* HD1080P-50 */
283         1920, 1080, SCHRO_CHROMA_422,
284         FALSE, TRUE,
285         50, 1, 1, 1,
286         1920, 1080, 0, 0,
287         64, 876, 512, 896,
288       0, 0, 0},
289   {0, 0, 0, 0,
290         15,                     /* DC2K */
291         2048, 1080, SCHRO_CHROMA_444,
292         FALSE, TRUE,
293         24, 1, 1, 1,
294         2048, 1080, 0, 0,
295         256, 3504, 2048, 3584,
296       3, 0, 0},
297   {0, 0, 0, 0,
298         16,                     /* DC4K */
299         4096, 2160, SCHRO_CHROMA_444,
300         FALSE, TRUE,
301         24, 1, 1, 1,
302         2048, 1536, 0, 0,
303         256, 3504, 2048, 3584,
304       3, 0, 0},
305 };
306 
307 static void
schro_video_format_set_std_video_format(DiracSequenceHeader * format,int index)308 schro_video_format_set_std_video_format (DiracSequenceHeader * format,
309     int index)
310 {
311 
312   if (index < 0 || index >= ARRAY_SIZE (schro_video_formats)) {
313     return;
314   }
315 
316   memcpy (format, schro_video_formats + index, sizeof (DiracSequenceHeader));
317 }
318 
319 typedef struct _SchroFrameRate SchroFrameRate;
320 struct _SchroFrameRate
321 {
322   int numerator;
323   int denominator;
324 };
325 
326 static const SchroFrameRate schro_frame_rates[] = {
327   {0, 0},
328   {24000, 1001},
329   {24, 1},
330   {25, 1},
331   {30000, 1001},
332   {30, 1},
333   {50, 1},
334   {60000, 1001},
335   {60, 1},
336   {15000, 1001},
337   {25, 2}
338 };
339 
340 static void
schro_video_format_set_std_frame_rate(DiracSequenceHeader * format,int index)341 schro_video_format_set_std_frame_rate (DiracSequenceHeader * format, int index)
342 {
343   if (index < 1 || index >= ARRAY_SIZE (schro_frame_rates)) {
344     return;
345   }
346 
347   format->frame_rate_numerator = schro_frame_rates[index].numerator;
348   format->frame_rate_denominator = schro_frame_rates[index].denominator;
349 }
350 
351 typedef struct _SchroPixelAspectRatio SchroPixelAspectRatio;
352 struct _SchroPixelAspectRatio
353 {
354   int numerator;
355   int denominator;
356 };
357 
358 static const SchroPixelAspectRatio schro_aspect_ratios[] = {
359   {0, 0},
360   {1, 1},
361   {10, 11},
362   {12, 11},
363   {40, 33},
364   {16, 11},
365   {4, 3}
366 };
367 
368 static void
schro_video_format_set_std_aspect_ratio(DiracSequenceHeader * format,int index)369 schro_video_format_set_std_aspect_ratio (DiracSequenceHeader * format,
370     int index)
371 {
372   if (index < 1 || index >= ARRAY_SIZE (schro_aspect_ratios)) {
373     return;
374   }
375 
376   format->aspect_ratio_numerator = schro_aspect_ratios[index].numerator;
377   format->aspect_ratio_denominator = schro_aspect_ratios[index].denominator;
378 
379 }
380 
381 typedef struct _SchroSignalRangeStruct SchroSignalRangeStruct;
382 struct _SchroSignalRangeStruct
383 {
384   int luma_offset;
385   int luma_excursion;
386   int chroma_offset;
387   int chroma_excursion;
388 };
389 
390 static const SchroSignalRangeStruct schro_signal_ranges[] = {
391   {0, 0, 0, 0},
392   {0, 255, 128, 255},
393   {16, 219, 128, 224},
394   {64, 876, 512, 896},
395   {256, 3504, 2048, 3584}
396 };
397 
398 static void
schro_video_format_set_std_signal_range(DiracSequenceHeader * format,int i)399 schro_video_format_set_std_signal_range (DiracSequenceHeader * format, int i)
400 {
401   if (i < 1 || i >= ARRAY_SIZE (schro_signal_ranges)) {
402     return;
403   }
404 
405   format->luma_offset = schro_signal_ranges[i].luma_offset;
406   format->luma_excursion = schro_signal_ranges[i].luma_excursion;
407   format->chroma_offset = schro_signal_ranges[i].chroma_offset;
408   format->chroma_excursion = schro_signal_ranges[i].chroma_excursion;
409 }
410 
411 typedef struct _SchroColourSpecStruct SchroColourSpecStruct;
412 struct _SchroColourSpecStruct
413 {
414   int colour_primaries;
415   int colour_matrix;
416   int transfer_function;
417 };
418 
419 static const SchroColourSpecStruct schro_colour_specs[] = {
420   {                             /* Custom */
421         SCHRO_COLOUR_PRIMARY_HDTV,
422         SCHRO_COLOUR_MATRIX_HDTV,
423       SCHRO_TRANSFER_CHAR_TV_GAMMA},
424   {                             /* SDTV 525 */
425         SCHRO_COLOUR_PRIMARY_SDTV_525,
426         SCHRO_COLOUR_MATRIX_SDTV,
427       SCHRO_TRANSFER_CHAR_TV_GAMMA},
428   {                             /* SDTV 625 */
429         SCHRO_COLOUR_PRIMARY_SDTV_625,
430         SCHRO_COLOUR_MATRIX_SDTV,
431       SCHRO_TRANSFER_CHAR_TV_GAMMA},
432   {                             /* HDTV */
433         SCHRO_COLOUR_PRIMARY_HDTV,
434         SCHRO_COLOUR_MATRIX_HDTV,
435       SCHRO_TRANSFER_CHAR_TV_GAMMA},
436   {                             /* Cinema */
437         SCHRO_COLOUR_PRIMARY_CINEMA,
438         SCHRO_COLOUR_MATRIX_HDTV,
439       SCHRO_TRANSFER_CHAR_TV_GAMMA}
440 };
441 
442 static void
schro_video_format_set_std_colour_spec(DiracSequenceHeader * format,int i)443 schro_video_format_set_std_colour_spec (DiracSequenceHeader * format, int i)
444 {
445   if (i < 0 || i >= ARRAY_SIZE (schro_colour_specs)) {
446     return;
447   }
448 
449   format->colour_primaries = schro_colour_specs[i].colour_primaries;
450   format->colour_matrix = schro_colour_specs[i].colour_matrix;
451   format->transfer_function = schro_colour_specs[i].transfer_function;
452 }
453 
454 
455 /* unpack */
456 
457 static void
schro_unpack_init_with_data(Unpack * unpack,unsigned char * data,int n_bytes,unsigned int guard_bit)458 schro_unpack_init_with_data (Unpack * unpack, unsigned char *data,
459     int n_bytes, unsigned int guard_bit)
460 {
461   memset (unpack, 0, sizeof (Unpack));
462 
463   unpack->data = data;
464   unpack->n_bits_left = 8 * n_bytes;
465   unpack->guard_bit = guard_bit;
466 }
467 
468 static unsigned int
schro_unpack_decode_bit(Unpack * unpack)469 schro_unpack_decode_bit (Unpack * unpack)
470 {
471   int bit;
472 
473   if (unpack->n_bits_left < 1) {
474     return unpack->guard_bit;
475   }
476   bit = (unpack->data[unpack->index >> 3] >> (7 - (unpack->index & 7))) & 1;
477   unpack->index++;
478   unpack->n_bits_left--;
479 
480   return bit;
481 }
482 
483 static unsigned int
schro_unpack_decode_uint(Unpack * unpack)484 schro_unpack_decode_uint (Unpack * unpack)
485 {
486   int count;
487   int value;
488 
489   count = 0;
490   value = 0;
491   while (!schro_unpack_decode_bit (unpack)) {
492     count++;
493     value <<= 1;
494     value |= schro_unpack_decode_bit (unpack);
495   }
496 
497   return (1 << count) - 1 + value;
498 }
499