root/liboggz/trunk/src/liboggz/dirac.c

Revision 3762, 5.0 kB (checked in by giles, 1 month ago)

Update dirac_parse_info for interlace spec changes.

After a patch by David Flynn.

Whether video is coded in frames or fields is set by the source_sampling
parameter in the video_format presets defined in table C.1, This can be
overridden by a custom value later in the sequence header. The field
order for interlaced video is defined by the preset only and cannot be
overridden.

Also normalize commas at the end of initializers.

Line 
1 /*
2   dirac.c
3 */
4 #include <stdint.h>
5
6 #include "dirac.h"
7
8 typedef struct
9 dirac_bs_s
10 {
11   uint8_t *p_start;
12   uint8_t *p;
13   uint8_t *p_end;
14
15   int     i_left;    /* i_count number of available bits */
16 } dirac_bs_t;
17
18 static inline void
19 dirac_bs_init( dirac_bs_t *s, void *p_data, int i_data )
20 {
21   s->p_start = p_data;
22   s->p       = p_data;
23   s->p_end   = s->p + i_data;
24   s->i_left  = 8;
25 }
26
27 static inline ogg_uint32_t
28 dirac_bs_read( dirac_bs_t *s, int i_count )
29 {
30    static ogg_uint32_t i_mask[33] =
31    {  0x00,
32       0x01,      0x03,      0x07,      0x0f,
33       0x1f,      0x3f,      0x7f,      0xff,
34       0x1ff,     0x3ff,     0x7ff,     0xfff,
35       0x1fff,    0x3fff,    0x7fff,    0xffff,
36       0x1ffff,   0x3ffff,   0x7ffff,   0xfffff,
37       0x1fffff,  0x3fffff,  0x7fffff,  0xffffff,
38       0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
39       0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
40   int      i_shr;
41   ogg_uint32_t i_result = 0;
42
43   while( i_count > 0 )
44   {
45     if( s->p >= s->p_end )
46     {
47       break;
48     }
49
50     if( ( i_shr = s->i_left - i_count ) >= 0 )
51     {
52       /* more in the buffer than requested */
53       i_result |= ( *s->p >> i_shr )&i_mask[i_count];
54       s->i_left -= i_count;
55       if( s->i_left == 0 )
56       {
57         s->p++;
58         s->i_left = 8;
59       }
60       return( i_result );
61     }
62     else
63     {
64         /* less in the buffer than requested */
65        i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
66        i_count  -= s->i_left;
67        s->p++;
68        s->i_left = 8;
69     }
70   }
71
72   return( i_result );
73 }
74
75 static inline void
76 dirac_bs_skip( dirac_bs_t *s, int i_count )
77 {
78   s->i_left -= i_count;
79
80   while( s->i_left <= 0 )
81   {
82     s->p++;
83     s->i_left += 8;
84   }
85 }
86
87 static ogg_uint32_t
88 dirac_uint ( dirac_bs_t *p_bs )
89 {
90   ogg_uint32_t count = 0, value = 0;
91   while( !dirac_bs_read ( p_bs, 1 ) ) {
92     count++;
93     value <<= 1;
94     value |= dirac_bs_read ( p_bs, 1 );
95   }
96
97   return (1<<count) - 1 + value;
98 }
99
100 static int
101 dirac_bool ( dirac_bs_t *p_bs )
102 {
103   return dirac_bs_read ( p_bs, 1 );
104 }
105
106 void
107 dirac_parse_info (dirac_info *info, unsigned char * data, long len)
108 {
109   char * buf;
110   dirac_bs_t bs;
111   ogg_uint32_t video_format;
112
113   static const struct {
114     ogg_uint32_t fps_numerator, fps_denominator;
115   } dirac_frate_tbl[] = { /* table 10.3 */
116     {1,1}, /* this first value is never used */
117     {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
118     {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2}
119   };
120
121   static const ogg_uint32_t dirac_vidfmt_frate[] = { /* table C.1 */
122     1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6
123   };
124
125   static const int dirac_source_sampling[] = { /* extracted from table C.1 */
126     0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
127   };
128   static const int dirac_top_field_first[] = { /* from table C.1 */
129     0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
130   };
131
132   static const struct {
133     ogg_uint32_t width, height;
134   } dirac_fsize_tbl[] = { /* table 10.3 framesize */
135     {640,460}, {24,1}, {176,120}, {352,240}, {352,288},
136     {704,480}, {704,576}, {720,480}, {720,576},
137     {1280, 720}, {1280, 720}, {1920, 1080}, {1920, 1080},
138     {1920, 1080}, {1920, 1080}, {2048, 1080}, {4096, 2160}
139   };
140
141   /* read in useful bits from sequence header */
142   dirac_bs_init( &bs, data, len);
143   dirac_bs_skip( &bs, 13*8); /* parse_info_header */
144   info->major_version = dirac_uint( &bs ); /* major_version */
145   info->minor_version = dirac_uint( &bs ); /* minor_version */
146   info->profile = dirac_uint( &bs ); /* profile */
147   info->level = dirac_uint( &bs ); /* level */
148   info->video_format = video_format = dirac_uint( &bs ); /* index */
149
150   info->width = dirac_fsize_tbl[video_format].width;
151   info->height = dirac_fsize_tbl[video_format].height;
152   if (dirac_bool( &bs )) {
153     info->width = dirac_uint( &bs ); /* frame_width */
154     info->height = dirac_uint( &bs ); /* frame_height */
155   }
156
157   if (dirac_bool( &bs )) {
158     info->chroma_format = dirac_uint( &bs ); /* chroma_format */
159   }
160
161   if (dirac_bool( &bs )) { /* custom_scan_format_flag */
162     int scan_format = dirac_uint( &bs ); /* scan_format */
163     if (scan_format < 2) {
164       info->interlaced = scan_format;
165     } else { /* other scan_format values are reserved */
166       info->interlaced = 0;
167     }
168   } else { /* no custom scan_format, use the preset value */
169     info->interlaced = dirac_source_sampling[video_format];
170   }
171   /* field order is set by video_format and cannot be custom */
172   info->top_field_first = dirac_top_field_first[video_format];
173
174   info->fps_numerator = dirac_frate_tbl[dirac_vidfmt_frate[video_format]].fps_numerator;
175   info->fps_denominator = dirac_frate_tbl[dirac_vidfmt_frate[video_format]].fps_denominator;
176   if (dirac_bool( &bs )) {
177     ogg_uint32_t frame_rate_index = dirac_uint( &bs );
178     info->fps_numerator = dirac_frate_tbl[frame_rate_index].fps_numerator;
179     info->fps_denominator = dirac_frate_tbl[frame_rate_index].fps_denominator;
180     if (frame_rate_index == 0) {
181       info->fps_numerator = dirac_uint( &bs );
182       info->fps_denominator = dirac_uint( &bs );
183     }
184   }
185 }
186
Note: See TracBrowser for help on using the browser.