1 |
689 |
jeremybenn |
/* PR debug/35065 */
|
2 |
|
|
/* { dg-do compile } */
|
3 |
|
|
/* { dg-options "-O2 -g -funroll-loops" } */
|
4 |
|
|
typedef int vlc_bool_t;
|
5 |
|
|
typedef __SIZE_TYPE__ size_t;
|
6 |
|
|
typedef struct vlc_object_t vlc_object_t;
|
7 |
|
|
typedef long long int64_t;
|
8 |
|
|
#if(__SIZEOF_INT__ >= 4)
|
9 |
|
|
typedef unsigned int uint32_t;
|
10 |
|
|
#else
|
11 |
|
|
typedef unsigned long uint32_t;
|
12 |
|
|
#endif
|
13 |
|
|
typedef unsigned char uint8_t;
|
14 |
|
|
typedef int64_t mtime_t;
|
15 |
|
|
typedef uint32_t vlc_fourcc_t;
|
16 |
|
|
typedef struct module_t module_t;
|
17 |
|
|
typedef struct es_format_t es_format_t;
|
18 |
|
|
typedef struct decoder_t decoder_t;
|
19 |
|
|
typedef struct decoder_sys_t decoder_sys_t;
|
20 |
|
|
typedef struct block_t block_t;
|
21 |
|
|
extern void* malloc (size_t);
|
22 |
|
|
enum vlc_module_properties {
|
23 |
|
|
VLC_MODULE_CB_OPEN, VLC_MODULE_CB_CLOSE, VLC_MODULE_NAME, };
|
24 |
|
|
struct es_format_t {
|
25 |
|
|
vlc_fourcc_t i_codec;
|
26 |
|
|
int i_extra;
|
27 |
|
|
void *p_extra;
|
28 |
|
|
};
|
29 |
|
|
struct block_t {
|
30 |
|
|
block_t *p_next;
|
31 |
|
|
uint32_t i_flags;
|
32 |
|
|
mtime_t i_pts;
|
33 |
|
|
mtime_t i_dts;
|
34 |
|
|
size_t i_buffer;
|
35 |
|
|
uint8_t *p_buffer;
|
36 |
|
|
};
|
37 |
|
|
block_t* block_New(void*, size_t);
|
38 |
|
|
block_t *nal_get_annexeb(decoder_t *, uint8_t *, int);
|
39 |
|
|
block_t *block_ChainGather (block_t *);
|
40 |
|
|
static inline block_t *block_Duplicate( block_t *p_block ) {
|
41 |
|
|
block_t *p_dup = block_New( ((void *)0), p_block->i_buffer );
|
42 |
|
|
p_dup->i_dts = p_block->i_dts;
|
43 |
|
|
p_dup->i_pts = p_block->i_pts;
|
44 |
|
|
}
|
45 |
|
|
static inline void block_ChainAppend( block_t **pp_list, block_t *p_block ) {
|
46 |
|
|
if( *pp_list == ((void *)0) ) {
|
47 |
|
|
}
|
48 |
|
|
else {
|
49 |
|
|
block_t *p = *pp_list;
|
50 |
|
|
while( p->p_next ) p = p->p_next;
|
51 |
|
|
p->p_next = p_block;
|
52 |
|
|
}
|
53 |
|
|
}
|
54 |
|
|
struct decoder_t {
|
55 |
|
|
decoder_sys_t * p_sys;
|
56 |
|
|
es_format_t fmt_in;
|
57 |
|
|
};
|
58 |
|
|
typedef struct bs_s {
|
59 |
|
|
uint8_t *p;
|
60 |
|
|
uint8_t *p_end;
|
61 |
|
|
int i_left;
|
62 |
|
|
} bs_t;
|
63 |
|
|
static inline uint32_t bs_read( bs_t *s, int i_count ) {
|
64 |
|
|
static uint32_t i_mask[33] = {
|
65 |
|
|
0x00, 0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
|
66 |
|
|
int i_shr;
|
67 |
|
|
uint32_t i_result = 0;
|
68 |
|
|
while( i_count > 0 ) {
|
69 |
|
|
if( s->p >= s->p_end ) {
|
70 |
|
|
break;
|
71 |
|
|
}
|
72 |
|
|
if( ( i_shr = s->i_left - i_count ) >= 0 ) {
|
73 |
|
|
i_result |= ( *s->p >> i_shr )&i_mask[i_count];
|
74 |
|
|
s->i_left -= i_count;
|
75 |
|
|
{
|
76 |
|
|
s->i_left = 8;
|
77 |
|
|
}
|
78 |
|
|
return( i_result );
|
79 |
|
|
}
|
80 |
|
|
{
|
81 |
|
|
i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
|
82 |
|
|
i_count -= s->i_left;
|
83 |
|
|
s->p++;
|
84 |
|
|
}
|
85 |
|
|
}
|
86 |
|
|
}
|
87 |
|
|
static inline uint32_t bs_read1( bs_t *s ) {
|
88 |
|
|
if( s->p < s->p_end ) {
|
89 |
|
|
unsigned int i_result;
|
90 |
|
|
s->i_left--;
|
91 |
|
|
i_result = ( *s->p >> s->i_left )&0x01;
|
92 |
|
|
if( s->i_left == 0 ) {
|
93 |
|
|
s->p++;
|
94 |
|
|
}
|
95 |
|
|
return i_result;
|
96 |
|
|
}
|
97 |
|
|
return 0;
|
98 |
|
|
}
|
99 |
|
|
int Open ( vlc_object_t * );
|
100 |
|
|
void Close( vlc_object_t * );
|
101 |
|
|
__attribute__((visibility("default"))) int vlc_entry__0_9_0f ( module_t *p_module ) {
|
102 |
|
|
{
|
103 |
|
|
module_t *p_submodule = p_module;
|
104 |
|
|
if (vlc_module_set (p_submodule, VLC_MODULE_CB_OPEN, (void *)(Open)) || vlc_module_set (p_submodule, VLC_MODULE_CB_CLOSE, (void *)(Close))) goto error;
|
105 |
|
|
}
|
106 |
|
|
error:
|
107 |
|
|
return -666;
|
108 |
|
|
}
|
109 |
|
|
typedef struct {
|
110 |
|
|
int i_nal_type;
|
111 |
|
|
int i_nal_ref_idc;
|
112 |
|
|
int i_frame_type;
|
113 |
|
|
int i_frame_num;
|
114 |
|
|
int i_bottom_field_flag;
|
115 |
|
|
int i_idr_pic_id;
|
116 |
|
|
int i_delta_pic_order_cnt0;
|
117 |
|
|
} slice_t;
|
118 |
|
|
struct decoder_sys_t {
|
119 |
|
|
vlc_bool_t b_slice;
|
120 |
|
|
block_t *p_frame;
|
121 |
|
|
vlc_bool_t b_sps;
|
122 |
|
|
vlc_bool_t b_pps;
|
123 |
|
|
vlc_bool_t b_header;
|
124 |
|
|
block_t *p_sps;
|
125 |
|
|
block_t *p_pps;
|
126 |
|
|
int i_pic_order_cnt_type;
|
127 |
|
|
slice_t slice;
|
128 |
|
|
};
|
129 |
|
|
enum { NAL_SLICE = 1, NAL_SLICE_IDR = 5, NAL_SPS = 7, NAL_AU_DELIMITER= 9 };
|
130 |
|
|
static block_t *ParseNALBlock( decoder_t *, block_t * );
|
131 |
|
|
int Open( vlc_object_t *p_this ) {
|
132 |
|
|
decoder_t *p_dec = (decoder_t*)p_this;
|
133 |
|
|
decoder_sys_t *p_sys;
|
134 |
|
|
if( p_dec->fmt_in.i_codec != ( ((uint32_t)'h') | ( ((uint32_t)'2') << 8 ) | ( ((uint32_t)'6') << 16 ) | ( ((uint32_t)'4') << 24 ) ) && ( p_dec->fmt_in.i_codec != ( ((uint32_t)'a') | ( ((uint32_t)'v') << 8 ) | ( ((uint32_t)'c') << 16 ) | ( ((uint32_t)'1') << 24 ) ) || p_dec->fmt_in.i_extra < 7 ) ) {
|
135 |
|
|
return -666;
|
136 |
|
|
}
|
137 |
|
|
if( ( p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) ) ) == ((void *)0) ) {
|
138 |
|
|
uint8_t *p = &((uint8_t*)p_dec->fmt_in.p_extra)[4];
|
139 |
|
|
int i_sps, i_pps;
|
140 |
|
|
int i;
|
141 |
|
|
i_sps = (*p++)&0x1f;
|
142 |
|
|
for( i = 0;
|
143 |
|
|
i < i_sps;
|
144 |
|
|
i++ ) {
|
145 |
|
|
int i_length = U16_AT( p );
|
146 |
|
|
block_t *p_sps = nal_get_annexeb( p_dec, p + 2, i_length );
|
147 |
|
|
ParseNALBlock( p_dec, p_sps );
|
148 |
|
|
}
|
149 |
|
|
}
|
150 |
|
|
}
|
151 |
|
|
static inline int bs_read_ue( bs_t *s ) {
|
152 |
|
|
int i = 0;
|
153 |
|
|
while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 ) {
|
154 |
|
|
i++;
|
155 |
|
|
}
|
156 |
|
|
return( ( 1 << i) - 1 + bs_read( s, i ) );
|
157 |
|
|
}
|
158 |
|
|
static inline int bs_read_se( bs_t *s ) {
|
159 |
|
|
int val = bs_read_ue( s );
|
160 |
|
|
}
|
161 |
|
|
block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag )
|
162 |
|
|
{
|
163 |
|
|
decoder_sys_t *p_sys = p_dec->p_sys;
|
164 |
|
|
block_t *p_pic = ((void *)0);
|
165 |
|
|
const int i_nal_type = p_frag->p_buffer[4]&0x1f;
|
166 |
|
|
if( ( !p_sys->b_sps || !p_sys->b_pps ) && i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR ) {
|
167 |
|
|
}
|
168 |
|
|
else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR ) {
|
169 |
|
|
int i_dec = 0, i_first_mb, i_slice_type;
|
170 |
|
|
slice_t slice;
|
171 |
|
|
bs_t s;
|
172 |
|
|
i_first_mb = bs_read_ue( &s );
|
173 |
|
|
switch( (i_slice_type = bs_read_ue( &s )) ) {
|
174 |
|
|
}
|
175 |
|
|
if( p_sys->i_pic_order_cnt_type == 0 ) {
|
176 |
|
|
slice.i_delta_pic_order_cnt0 = bs_read_se( &s );
|
177 |
|
|
}
|
178 |
|
|
if( slice.i_frame_num != p_sys->slice.i_frame_num
|
179 |
|
|
|| slice.i_nal_ref_idc != p_sys->slice.i_nal_ref_idc )
|
180 |
|
|
if( (slice.i_bottom_field_flag != -1)
|
181 |
|
|
&& (slice.i_bottom_field_flag != p_sys->slice.i_bottom_field_flag) )
|
182 |
|
|
if( p_sys->i_pic_order_cnt_type == 0 && ( slice.i_nal_type != p_sys->slice.i_nal_type || slice.i_idr_pic_id != p_sys->slice.i_idr_pic_id ) )
|
183 |
|
|
do {
|
184 |
|
|
if( !p_sys->b_header && p_sys->slice.i_frame_type != 0x0002)
|
185 |
|
|
break;
|
186 |
|
|
if( p_sys->slice.i_frame_type == 0x0002 && p_sys->p_sps && p_sys->p_pps ) {
|
187 |
|
|
block_t *p_sps = block_Duplicate( p_sys->p_sps );
|
188 |
|
|
block_t *p_pps = block_Duplicate( p_sys->p_pps );
|
189 |
|
|
p_sps->i_pts = p_sys->p_frame->i_pts;
|
190 |
|
|
block_ChainAppend( &p_sps, p_pps );
|
191 |
|
|
block_ChainAppend( &p_sps, p_sys->p_frame );
|
192 |
|
|
p_sys->b_header = 1;
|
193 |
|
|
p_pic = block_ChainGather( p_sps );
|
194 |
|
|
}
|
195 |
|
|
} while(0);
|
196 |
|
|
}
|
197 |
|
|
else if( i_nal_type == NAL_SPS ) {
|
198 |
|
|
bs_t s;
|
199 |
|
|
if( p_sys->i_pic_order_cnt_type == 0 ) {
|
200 |
|
|
}
|
201 |
|
|
else if( p_sys->i_pic_order_cnt_type == 1 ) {
|
202 |
|
|
int i_cycle;
|
203 |
|
|
i_cycle = bs_read_ue( &s );
|
204 |
|
|
while( i_cycle > 0 ) {
|
205 |
|
|
bs_read_se(&s );
|
206 |
|
|
}
|
207 |
|
|
}
|
208 |
|
|
bs_read_ue( &s );
|
209 |
|
|
if( p_sys->b_slice )
|
210 |
|
|
do {
|
211 |
|
|
if( !p_sys->b_header && p_sys->slice.i_frame_type != 0x0002)
|
212 |
|
|
break;
|
213 |
|
|
if( p_sys->slice.i_frame_type == 0x0002
|
214 |
|
|
&& p_sys->p_sps && p_sys->p_pps )
|
215 |
|
|
{
|
216 |
|
|
block_t *p_sps = block_Duplicate( p_sys->p_sps );
|
217 |
|
|
block_t *p_pps = block_Duplicate( p_sys->p_pps );
|
218 |
|
|
p_sps->i_dts = p_sys->p_frame->i_dts;
|
219 |
|
|
p_sps->i_pts = p_sys->p_frame->i_pts;
|
220 |
|
|
block_ChainAppend( &p_sps, p_pps );
|
221 |
|
|
block_ChainAppend( &p_sps, p_sys->p_frame );
|
222 |
|
|
p_pic = block_ChainGather( p_sps );
|
223 |
|
|
}
|
224 |
|
|
p_pic->i_flags |= p_sys->slice.i_frame_type;
|
225 |
|
|
} while(0);
|
226 |
|
|
}
|
227 |
|
|
block_ChainAppend( &p_sys->p_frame, p_frag );
|
228 |
|
|
}
|