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