[svn] / trunk / xvidcore / src / bitstream / bitstream.c Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/bitstream/bitstream.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 514 - (view) (download)

1 : edgomez 469 /*****************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - Bitstream reader/writer functions -
5 :     *
6 : suxen_drol 499 * Copyright (C) 2001-2002 - Peter Ross <pross@xvid.org>
7 : edgomez 469 *
8 :     * This program is an implementation of a part of one or more MPEG-4
9 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
10 :     * to use this software module in hardware or software products are
11 :     * advised that its use may infringe existing patents or copyrights, and
12 :     * any such use would be at such party's own risk. The original
13 :     * developer of this software module and his/her company, and subsequent
14 :     * editors and their companies, will have no liability for use of this
15 :     * software or modifications or derivatives thereof.
16 :     *
17 :     * This program is free software ; you can redistribute it and/or modify
18 :     * it under the terms of the GNU General Public License as published by
19 :     * the Free Software Foundation ; either version 2 of the License, or
20 :     * (at your option) any later version.
21 :     *
22 :     * This program is distributed in the hope that it will be useful,
23 :     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
24 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 :     * GNU General Public License for more details.
26 :     *
27 :     * You should have received a copy of the GNU General Public License
28 :     * along with this program ; if not, write to the Free Software
29 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 :     *
31 : edgomez 514 * $Id: bitstream.c,v 1.33 2002-09-22 17:01:36 edgomez Exp $
32 : edgomez 469 *
33 :     ****************************************************************************/
34 : Isibaar 3
35 :     #include "bitstream.h"
36 :     #include "zigzag.h"
37 : Isibaar 4 #include "../quant/quant_matrix.h"
38 : Isibaar 3
39 : edgomez 469 /*****************************************************************************
40 :     * Functions
41 :     ****************************************************************************/
42 : chenm001 124
43 : edgomez 195 static uint32_t __inline
44 :     log2bin(uint32_t value)
45 : Isibaar 3 {
46 : chenm001 124 /* Changed by Chenm001 */
47 :     #ifndef WIN32
48 : Isibaar 3 int n = 0;
49 : edgomez 195
50 :     while (value) {
51 : Isibaar 3 value >>= 1;
52 :     n++;
53 :     }
54 :     return n;
55 : chenm001 124 #else
56 : edgomez 195 __asm {
57 : suxen_drol 206 bsr eax, value
58 :     inc eax
59 :     }
60 : chenm001 124 #endif
61 : Isibaar 3 }
62 :    
63 :    
64 : edgomez 195 static const uint32_t intra_dc_threshold_table[] = {
65 :     32, /* never use */
66 : Isibaar 3 13,
67 :     15,
68 :     17,
69 :     19,
70 :     21,
71 :     23,
72 :     1,
73 :     };
74 :    
75 :    
76 : edgomez 195 void
77 :     bs_get_matrix(Bitstream * bs,
78 :     uint8_t * matrix)
79 :     {
80 :     int i = 0;
81 :     int last, value = 0;
82 : Isibaar 4
83 : edgomez 195 do {
84 :     last = value;
85 :     value = BitstreamGetBits(bs, 8);
86 :     matrix[scan_tables[0][i++]] = value;
87 :     }
88 :     while (value != 0 && i < 64);
89 : chenm001 223 i--; // fix little bug at coeff not full
90 : edgomez 195
91 :     while (i < 64) {
92 :     matrix[scan_tables[0][i++]] = last;
93 :     }
94 :     }
95 :    
96 : suxen_drol 248
97 :    
98 :     // for PVOP addbits == fcode - 1
99 :     // for BVOP addbits == max(fcode,bcode) - 1
100 :     // returns mbpos
101 :     int
102 : suxen_drol 252 read_video_packet_header(Bitstream *bs, const int addbits, int * quant)
103 : suxen_drol 248 {
104 :     int nbits;
105 :     int mbnum;
106 :     int hec;
107 :    
108 : suxen_drol 252 nbits = NUMBITS_VP_RESYNC_MARKER + addbits;
109 : suxen_drol 248
110 :     BitstreamSkip(bs, BitstreamNumBitsToByteAlign(bs));
111 :     BitstreamSkip(bs, nbits);
112 :    
113 : suxen_drol 252 DPRINTF(DPRINTF_STARTCODE, "<video_packet_header>");
114 :    
115 : suxen_drol 248 // if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
116 :     // hec
117 :     // vop_width
118 :     // marker_bit
119 :     // vop_height
120 :     // marker_bit
121 :    
122 :     //}
123 :    
124 :     mbnum = BitstreamGetBits(bs, 9);
125 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "mbnum %i", mbnum);
126 : suxen_drol 248
127 :     // if (dec->shape != VIDOBJLAY_SHAPE_BINARYONLY)
128 : suxen_drol 252 *quant = BitstreamGetBits(bs, 5);
129 :     DPRINTF(DPRINTF_HEADER, "quant %i", *quant);
130 : suxen_drol 248
131 :     // if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR)
132 :     hec = BitstreamGetBit(bs);
133 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "header_extension_code %i", hec);
134 : suxen_drol 248 // if (hec)
135 :     // .. decoder hec-header ...
136 :    
137 :     return mbnum;
138 :     }
139 :    
140 :    
141 :    
142 : Isibaar 3 /*
143 :     decode headers
144 :     returns coding_type, or -1 if error
145 :     */
146 :    
147 : suxen_drol 252 #define VIDOBJ_START_CODE_MASK 0x0000001f
148 :     #define VIDOBJLAY_START_CODE_MASK 0x0000000f
149 :    
150 : edgomez 195 int
151 :     BitstreamReadHeaders(Bitstream * bs,
152 :     DECODER * dec,
153 :     uint32_t * rounding,
154 :     uint32_t * quant,
155 :     uint32_t * fcode_forward,
156 :     uint32_t * fcode_backward,
157 :     uint32_t * intra_dc_threshold)
158 : Isibaar 3 {
159 :     uint32_t vol_ver_id;
160 : chenm001 156 static uint32_t time_increment_resolution;
161 : Isibaar 3 uint32_t coding_type;
162 :     uint32_t start_code;
163 : edgomez 195 uint32_t time_incr = 0;
164 : edgomez 478 int32_t time_increment = 0;
165 : chenm001 156
166 : edgomez 195 do {
167 : Isibaar 3 BitstreamByteAlign(bs);
168 :     start_code = BitstreamShowBits(bs, 32);
169 :    
170 : edgomez 195 if (start_code == VISOBJSEQ_START_CODE) {
171 : suxen_drol 252
172 :     int profile;
173 :    
174 :     DPRINTF(DPRINTF_STARTCODE, "<visual_object_sequence>");
175 :    
176 : edgomez 195 BitstreamSkip(bs, 32); // visual_object_sequence_start_code
177 : suxen_drol 252 profile = BitstreamGetBits(bs, 8); // profile_and_level_indication
178 :    
179 :     DPRINTF(DPRINTF_HEADER, "profile_and_level_indication %i", profile);
180 :    
181 : edgomez 195 } else if (start_code == VISOBJSEQ_STOP_CODE) {
182 : suxen_drol 252
183 : edgomez 195 BitstreamSkip(bs, 32); // visual_object_sequence_stop_code
184 : suxen_drol 252
185 :     DPRINTF(DPRINTF_STARTCODE, "</visual_object_sequence>");
186 :    
187 : edgomez 195 } else if (start_code == VISOBJ_START_CODE) {
188 : suxen_drol 252
189 :     DPRINTF(DPRINTF_STARTCODE, "<visual_object>");
190 :    
191 : edgomez 195 BitstreamSkip(bs, 32); // visual_object_start_code
192 :     if (BitstreamGetBit(bs)) // is_visual_object_identified
193 : Isibaar 3 {
194 : edgomez 195 vol_ver_id = BitstreamGetBits(bs, 4); // visual_object_ver_id
195 : suxen_drol 252 DPRINTF(DPRINTF_HEADER,"ver_id %i", vol_ver_id);
196 : edgomez 195 BitstreamSkip(bs, 3); // visual_object_priority
197 :     } else {
198 : Isibaar 3 vol_ver_id = 1;
199 :     }
200 :    
201 :     if (BitstreamShowBits(bs, 4) != VISOBJ_TYPE_VIDEO) // visual_object_type
202 :     {
203 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "visual_object_type != video");
204 : Isibaar 3 return -1;
205 :     }
206 :     BitstreamSkip(bs, 4);
207 :    
208 :     // video_signal_type
209 :    
210 : edgomez 195 if (BitstreamGetBit(bs)) // video_signal_type
211 : Isibaar 3 {
212 : suxen_drol 252 DPRINTF(DPRINTF_HEADER,"+ video_signal_type");
213 : edgomez 195 BitstreamSkip(bs, 3); // video_format
214 :     BitstreamSkip(bs, 1); // video_range
215 :     if (BitstreamGetBit(bs)) // color_description
216 : Isibaar 3 {
217 : suxen_drol 252 DPRINTF(DPRINTF_HEADER,"+ color_description");
218 : edgomez 195 BitstreamSkip(bs, 8); // color_primaries
219 :     BitstreamSkip(bs, 8); // transfer_characteristics
220 :     BitstreamSkip(bs, 8); // matrix_coefficients
221 : Isibaar 3 }
222 :     }
223 : suxen_drol 252 } else if ((start_code & ~VIDOBJ_START_CODE_MASK) == VIDOBJ_START_CODE) {
224 :    
225 :     DPRINTF(DPRINTF_STARTCODE, "<video_object>");
226 :     DPRINTF(DPRINTF_HEADER, "vo id %i", start_code & VIDOBJ_START_CODE_MASK);
227 :    
228 : edgomez 195 BitstreamSkip(bs, 32); // video_object_start_code
229 : suxen_drol 252
230 :     } else if ((start_code & ~VIDOBJLAY_START_CODE_MASK) == VIDOBJLAY_START_CODE) {
231 :    
232 :     DPRINTF(DPRINTF_STARTCODE, "<video_object_layer>");
233 :     DPRINTF(DPRINTF_HEADER, "vol id %i", start_code & VIDOBJLAY_START_CODE_MASK);
234 :    
235 : edgomez 195 BitstreamSkip(bs, 32); // video_object_layer_start_code
236 : Isibaar 3
237 : edgomez 195 BitstreamSkip(bs, 1); // random_accessible_vol
238 : Isibaar 3
239 :     // video_object_type_indication
240 : edgomez 195 if (BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_SIMPLE && BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_CORE && BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_MAIN && BitstreamShowBits(bs, 8) != 0) // BUGGY DIVX
241 : Isibaar 3 {
242 : suxen_drol 252 DPRINTF(DPRINTF_ERROR,"video_object_type_indication %i not supported ",
243 :     BitstreamShowBits(bs, 8));
244 : Isibaar 3 return -1;
245 :     }
246 :     BitstreamSkip(bs, 8);
247 :    
248 :    
249 : edgomez 195 if (BitstreamGetBit(bs)) // is_object_layer_identifier
250 : Isibaar 3 {
251 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "+ is_object_layer_identifier");
252 : edgomez 195 vol_ver_id = BitstreamGetBits(bs, 4); // video_object_layer_verid
253 : suxen_drol 252 DPRINTF(DPRINTF_HEADER,"ver_id %i", vol_ver_id);
254 : edgomez 195 BitstreamSkip(bs, 3); // video_object_layer_priority
255 :     } else {
256 : Isibaar 3 vol_ver_id = 1;
257 :     }
258 :    
259 :     if (BitstreamGetBits(bs, 4) == VIDOBJLAY_AR_EXTPAR) // aspect_ratio_info
260 :     {
261 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "+ aspect_ratio_info");
262 : edgomez 195 BitstreamSkip(bs, 8); // par_width
263 :     BitstreamSkip(bs, 8); // par_height
264 : Isibaar 3 }
265 :    
266 : edgomez 195 if (BitstreamGetBit(bs)) // vol_control_parameters
267 : Isibaar 3 {
268 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "+ vol_control_parameters");
269 : edgomez 195 BitstreamSkip(bs, 2); // chroma_format
270 :     dec->low_delay = BitstreamGetBit(bs); // low_delay
271 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "low_delay %i", dec->low_delay);
272 : edgomez 195 if (BitstreamGetBit(bs)) // vbv_parameters
273 : Isibaar 3 {
274 : suxen_drol 252 DPRINTF(DPRINTF_HEADER,"+ vbv_parameters");
275 : edgomez 195 BitstreamSkip(bs, 15); // first_half_bitrate
276 : Isibaar 3 READ_MARKER();
277 : edgomez 195 BitstreamSkip(bs, 15); // latter_half_bitrate
278 : Isibaar 3 READ_MARKER();
279 : edgomez 195 BitstreamSkip(bs, 15); // first_half_vbv_buffer_size
280 : Isibaar 3 READ_MARKER();
281 : edgomez 195 BitstreamSkip(bs, 3); // latter_half_vbv_buffer_size
282 :     BitstreamSkip(bs, 11); // first_half_vbv_occupancy
283 : Isibaar 3 READ_MARKER();
284 : edgomez 195 BitstreamSkip(bs, 15); // latter_half_vbv_occupancy
285 : Isibaar 3 READ_MARKER();
286 : edgomez 195
287 : Isibaar 3 }
288 :     }
289 :    
290 :     dec->shape = BitstreamGetBits(bs, 2); // video_object_layer_shape
291 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "shape %i", dec->shape);
292 : edgomez 195
293 :     if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1) {
294 :     BitstreamSkip(bs, 4); // video_object_layer_shape_extension
295 : Isibaar 3 }
296 :    
297 :     READ_MARKER();
298 :    
299 : chenm001 156 // *************************** for decode B-frame time ***********************
300 :     time_increment_resolution = BitstreamGetBits(bs, 16); // vop_time_increment_resolution
301 : suxen_drol 252
302 :     DPRINTF(DPRINTF_HEADER,"vop_time_increment_resolution %i", time_increment_resolution);
303 :    
304 : chl 313 // time_increment_resolution--;
305 : suxen_drol 252
306 : edgomez 195 if (time_increment_resolution > 0) {
307 : chl 313 dec->time_inc_bits = log2bin(time_increment_resolution-1);
308 : edgomez 195 } else {
309 : Isibaar 3 // dec->time_inc_bits = 0;
310 :     // for "old" xvid compatibility, set time_inc_bits = 1
311 :     dec->time_inc_bits = 1;
312 :     }
313 :    
314 :     READ_MARKER();
315 :    
316 : edgomez 195 if (BitstreamGetBit(bs)) // fixed_vop_rate
317 : Isibaar 3 {
318 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "+ fixed_vop_rate");
319 : Isibaar 3 BitstreamSkip(bs, dec->time_inc_bits); // fixed_vop_time_increment
320 :     }
321 :    
322 : edgomez 195 if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) {
323 : Isibaar 3
324 : edgomez 195 if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR) {
325 : Isibaar 3 uint32_t width, height;
326 :    
327 :     READ_MARKER();
328 : edgomez 195 width = BitstreamGetBits(bs, 13); // video_object_layer_width
329 : Isibaar 3 READ_MARKER();
330 : edgomez 195 height = BitstreamGetBits(bs, 13); // video_object_layer_height
331 : Isibaar 3 READ_MARKER();
332 :    
333 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "width %i", width);
334 :     DPRINTF(DPRINTF_HEADER, "height %i", height);
335 :    
336 : chenm001 294 // for auto set width & height
337 :     if (dec->width == 0)
338 :     dec->width = width;
339 :     if (dec->height == 0)
340 :     dec->height = height;
341 :    
342 : edgomez 195 if (width != dec->width || height != dec->height) {
343 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "XVID_DEC_PARAM width/height does not match bitstream");
344 : Isibaar 3 return -1;
345 :     }
346 :    
347 :     }
348 : h 69
349 : suxen_drol 252 dec->interlacing = BitstreamGetBit(bs);
350 :     DPRINTF(DPRINTF_HEADER, "interlace", dec->interlacing);
351 : Isibaar 3
352 : edgomez 195 if (!BitstreamGetBit(bs)) // obmc_disable
353 : Isibaar 3 {
354 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "obmc_disabled==false not supported");
355 : Isibaar 3 // TODO
356 :     // fucking divx4.02 has this enabled
357 :     }
358 :    
359 : edgomez 195 if (BitstreamGetBits(bs, (vol_ver_id == 1 ? 1 : 2))) // sprite_enable
360 : Isibaar 3 {
361 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "spriate_enabled not supported");
362 : Isibaar 3 return -1;
363 :     }
364 : edgomez 195
365 :     if (vol_ver_id != 1 &&
366 :     dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
367 :     BitstreamSkip(bs, 1); // sadct_disable
368 : Isibaar 3 }
369 :    
370 : edgomez 195 if (BitstreamGetBit(bs)) // not_8_bit
371 : Isibaar 3 {
372 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "not_8_bit==true (ignored)");
373 : Isibaar 3 dec->quant_bits = BitstreamGetBits(bs, 4); // quant_precision
374 : edgomez 195 BitstreamSkip(bs, 4); // bits_per_pixel
375 :     } else {
376 : Isibaar 3 dec->quant_bits = 5;
377 :     }
378 :    
379 : edgomez 195 if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE) {
380 :     BitstreamSkip(bs, 1); // no_gray_quant_update
381 :     BitstreamSkip(bs, 1); // composition_method
382 :     BitstreamSkip(bs, 1); // linear_composition
383 : Isibaar 3 }
384 :    
385 : edgomez 195 dec->quant_type = BitstreamGetBit(bs); // quant_type
386 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "quant_type %i", dec->quant_type);
387 : Isibaar 3
388 : edgomez 195 if (dec->quant_type) {
389 :     if (BitstreamGetBit(bs)) // load_intra_quant_mat
390 : Isibaar 3 {
391 : Isibaar 20 uint8_t matrix[64];
392 : edgomez 195
393 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "load_intra_quant_mat");
394 :    
395 : Isibaar 4 bs_get_matrix(bs, matrix);
396 :     set_intra_matrix(matrix);
397 : edgomez 195 } else
398 : Isibaar 20 set_intra_matrix(get_default_intra_matrix());
399 : Isibaar 4
400 : edgomez 195 if (BitstreamGetBit(bs)) // load_inter_quant_mat
401 : Isibaar 3 {
402 : edgomez 195 uint8_t matrix[64];
403 : suxen_drol 252
404 :     DPRINTF(DPRINTF_HEADER, "load_inter_quant_mat");
405 : edgomez 195
406 : Isibaar 4 bs_get_matrix(bs, matrix);
407 :     set_inter_matrix(matrix);
408 : edgomez 195 } else
409 : Isibaar 20 set_inter_matrix(get_default_inter_matrix());
410 : Isibaar 3
411 : edgomez 195 if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE) {
412 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "greyscale matrix not supported");
413 : Isibaar 3 return -1;
414 :     }
415 : Isibaar 4
416 : Isibaar 3 }
417 :    
418 : edgomez 195
419 :     if (vol_ver_id != 1) {
420 : edgomez 514 DPRINTF(DPRINTF_DEBUG, "QUARTERPEL BITSTREAM");
421 : Isibaar 333 dec->quarterpel = BitstreamGetBit(bs); // quarter_sample
422 : Isibaar 3 }
423 : Isibaar 333 else
424 :     dec->quarterpel = 0;
425 :    
426 : Isibaar 3
427 : edgomez 195 if (!BitstreamGetBit(bs)) // complexity_estimation_disable
428 : Isibaar 3 {
429 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "complexity_estimation not supported");
430 : Isibaar 3 return -1;
431 :     }
432 :    
433 : suxen_drol 252 BitstreamSkip(bs, 1); // resync_marker_disable
434 : Isibaar 3
435 : edgomez 195 if (BitstreamGetBit(bs)) // data_partitioned
436 : Isibaar 3 {
437 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "data_partitioned not supported");
438 : edgomez 195 BitstreamSkip(bs, 1); // reversible_vlc
439 : Isibaar 3 }
440 :    
441 : edgomez 195 if (vol_ver_id != 1) {
442 :     if (BitstreamGetBit(bs)) // newpred_enable
443 : Isibaar 3 {
444 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "+ newpred_enable");
445 : edgomez 195 BitstreamSkip(bs, 2); // requested_upstream_message_type
446 :     BitstreamSkip(bs, 1); // newpred_segment_type
447 : Isibaar 3 }
448 : edgomez 195 if (BitstreamGetBit(bs)) // reduced_resolution_vop_enable
449 : Isibaar 3 {
450 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "reduced_resolution_vop not supported");
451 : Isibaar 3 return -1;
452 :     }
453 :     }
454 : edgomez 195
455 :     if ((dec->scalability = BitstreamGetBit(bs))) // scalability
456 : Isibaar 3 {
457 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "scalability not supported");
458 : Isibaar 3 return -1;
459 :     }
460 : edgomez 195 } else // dec->shape == BINARY_ONLY
461 : Isibaar 3 {
462 : edgomez 195 if (vol_ver_id != 1) {
463 : Isibaar 3 if (BitstreamGetBit(bs)) // scalability
464 :     {
465 : suxen_drol 252 DPRINTF(DPRINTF_ERROR, "scalability not supported");
466 : Isibaar 3 return -1;
467 :     }
468 :     }
469 : edgomez 195 BitstreamSkip(bs, 1); // resync_marker_disable
470 : Isibaar 3
471 :     }
472 :    
473 : edgomez 195 } else if (start_code == GRPOFVOP_START_CODE) {
474 : suxen_drol 252
475 :     DPRINTF(DPRINTF_STARTCODE, "<group_of_vop>");
476 :    
477 : Isibaar 3 BitstreamSkip(bs, 32);
478 :     {
479 :     int hours, minutes, seconds;
480 : edgomez 195
481 : Isibaar 3 hours = BitstreamGetBits(bs, 5);
482 :     minutes = BitstreamGetBits(bs, 6);
483 :     READ_MARKER();
484 :     seconds = BitstreamGetBits(bs, 6);
485 : suxen_drol 252
486 :     DPRINTF(DPRINTF_HEADER, "time %ih%im%is", hours);
487 : Isibaar 3 }
488 : edgomez 195 BitstreamSkip(bs, 1); // closed_gov
489 :     BitstreamSkip(bs, 1); // broken_link
490 : suxen_drol 252
491 : edgomez 195 } else if (start_code == VOP_START_CODE) {
492 : suxen_drol 252
493 :     DPRINTF(DPRINTF_STARTCODE, "<vop>");
494 :    
495 : edgomez 195 BitstreamSkip(bs, 32); // vop_start_code
496 : Isibaar 3
497 : edgomez 195 coding_type = BitstreamGetBits(bs, 2); // vop_coding_type
498 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "coding_type %i", coding_type);
499 : Isibaar 3
500 : chenm001 156 // *************************** for decode B-frame time ***********************
501 : edgomez 195 while (BitstreamGetBit(bs) != 0) // time_base
502 : chenm001 156 time_incr++;
503 : edgomez 195
504 : Isibaar 3 READ_MARKER();
505 : edgomez 195
506 :     if (dec->time_inc_bits) {
507 : chenm001 156 time_increment = (BitstreamGetBits(bs, dec->time_inc_bits)); // vop_time_increment
508 : Isibaar 3 }
509 : suxen_drol 240
510 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "time_base %i", time_incr);
511 :     DPRINTF(DPRINTF_HEADER, "time_increment %i", time_increment);
512 :    
513 :     DPRINTF(DPRINTF_TIMECODE, "%c %i:%i",
514 : suxen_drol 240 coding_type == I_VOP ? 'I' : coding_type == P_VOP ? 'P' : 'B',
515 :     time_incr, time_increment);
516 :    
517 : edgomez 195 if (coding_type != B_VOP) {
518 :     dec->last_time_base = dec->time_base;
519 : chenm001 156 dec->time_base += time_incr;
520 : chl 316 dec->time = time_increment;
521 :    
522 :     /* dec->time_base * time_increment_resolution +
523 : edgomez 195 time_increment;
524 : chl 316 */ dec->time_pp = (uint32_t)
525 : chl 313 (time_increment_resolution + dec->time - dec->last_non_b_time)%time_increment_resolution;
526 : edgomez 195 dec->last_non_b_time = dec->time;
527 :     } else {
528 : chl 316 dec->time = time_increment;
529 :     /*
530 : edgomez 195 (dec->last_time_base +
531 : chl 316 time_incr) * time_increment_resolution + time_increment;
532 :     */
533 : chl 313 dec->time_bp = (uint32_t)
534 :     (time_increment_resolution + dec->last_non_b_time - dec->time)%time_increment_resolution;
535 : chenm001 156 }
536 : Isibaar 3
537 :     READ_MARKER();
538 :    
539 : edgomez 195 if (!BitstreamGetBit(bs)) // vop_coded
540 : Isibaar 3 {
541 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "vop_coded==false");
542 : Isibaar 3 return N_VOP;
543 :     }
544 :    
545 :     /* if (newpred_enable)
546 : edgomez 195 {
547 :     }
548 :     */
549 : Isibaar 3
550 : chenm001 156 // fix a little bug by MinChen <chenm002@163.com>
551 : edgomez 195 if ((dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) &&
552 :     (coding_type == P_VOP)) {
553 : Isibaar 3 *rounding = BitstreamGetBit(bs); // rounding_type
554 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "rounding %i", *rounding);
555 : Isibaar 3 }
556 :    
557 :     /* if (reduced_resolution_enable)
558 : edgomez 195 {
559 :     }
560 :     */
561 : Isibaar 3
562 : edgomez 195 if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
563 : Isibaar 3 uint32_t width, height;
564 :     uint32_t horiz_mc_ref, vert_mc_ref;
565 : edgomez 195
566 : Isibaar 3 width = BitstreamGetBits(bs, 13);
567 :     READ_MARKER();
568 :     height = BitstreamGetBits(bs, 13);
569 :     READ_MARKER();
570 :     horiz_mc_ref = BitstreamGetBits(bs, 13);
571 :     READ_MARKER();
572 :     vert_mc_ref = BitstreamGetBits(bs, 13);
573 :     READ_MARKER();
574 :    
575 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "width %i", width);
576 :     DPRINTF(DPRINTF_HEADER, "height %i", height);
577 :     DPRINTF(DPRINTF_HEADER, "horiz_mc_ref %i", horiz_mc_ref);
578 :     DPRINTF(DPRINTF_HEADER, "vert_mc_ref %i", vert_mc_ref);
579 : Isibaar 3
580 : edgomez 195 BitstreamSkip(bs, 1); // change_conv_ratio_disable
581 :     if (BitstreamGetBit(bs)) // vop_constant_alpha
582 : Isibaar 3 {
583 : edgomez 195 BitstreamSkip(bs, 8); // vop_constant_alpha_value
584 : Isibaar 3 }
585 :     }
586 :    
587 : edgomez 195
588 :     if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) {
589 : Isibaar 3 // intra_dc_vlc_threshold
590 : edgomez 195 *intra_dc_threshold =
591 :     intra_dc_threshold_table[BitstreamGetBits(bs, 3)];
592 : Isibaar 3
593 : edgomez 195 if (dec->interlacing) {
594 : suxen_drol 252 dec->top_field_first = BitstreamGetBit(bs);
595 :     DPRINTF(DPRINTF_HEADER, "interlace top_field_first %i", dec->top_field_first);
596 :     dec->alternate_vertical_scan = BitstreamGetBit(bs);
597 :     DPRINTF(DPRINTF_HEADER, "interlace alternate_vertical_scan %i", dec->alternate_vertical_scan);
598 :    
599 : h 69 }
600 : Isibaar 3 }
601 : edgomez 195
602 :     if ((*quant = BitstreamGetBits(bs, dec->quant_bits)) < 1) // vop_quant
603 : Isibaar 157 *quant = 1;
604 :    
605 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "quant %i", *quant);
606 : edgomez 195
607 :     if (coding_type != I_VOP) {
608 :     *fcode_forward = BitstreamGetBits(bs, 3); // fcode_forward
609 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "fcode_forward %i", *fcode_forward);
610 : Isibaar 3 }
611 : edgomez 195
612 :     if (coding_type == B_VOP) {
613 :     *fcode_backward = BitstreamGetBits(bs, 3); // fcode_backward
614 : suxen_drol 252 DPRINTF(DPRINTF_HEADER, "fcode_backward %i", *fcode_backward);
615 : Isibaar 3 }
616 : edgomez 195 if (!dec->scalability) {
617 :     if ((dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) &&
618 :     (coding_type != I_VOP)) {
619 :     BitstreamSkip(bs, 1); // vop_shape_coding_type
620 : chenm001 156 }
621 :     }
622 : Isibaar 3 return coding_type;
623 : suxen_drol 252
624 : edgomez 195 } else if (start_code == USERDATA_START_CODE) {
625 : suxen_drol 252
626 :     DPRINTF(DPRINTF_STARTCODE, "<user_data>");
627 :    
628 : edgomez 195 BitstreamSkip(bs, 32); // user_data_start_code
629 : suxen_drol 252
630 : edgomez 195 } else // start_code == ?
631 : Isibaar 3 {
632 : edgomez 195 if (BitstreamShowBits(bs, 24) == 0x000001) {
633 : suxen_drol 252 DPRINTF(DPRINTF_STARTCODE, "<unknown: %x>", BitstreamShowBits(bs, 32));
634 : Isibaar 3 }
635 :     BitstreamSkip(bs, 8);
636 :     }
637 :     }
638 :     while ((BitstreamPos(bs) >> 3) < bs->length);
639 :    
640 : suxen_drol 233 //DPRINTF("*** WARNING: no vop_start_code found");
641 : edgomez 195 return -1; /* ignore it */
642 : Isibaar 3 }
643 :    
644 :    
645 :     /* write custom quant matrix */
646 :    
647 : edgomez 195 static void
648 :     bs_put_matrix(Bitstream * bs,
649 :     const int16_t * matrix)
650 : Isibaar 3 {
651 :     int i, j;
652 :     const int last = matrix[scan_tables[0][63]];
653 :    
654 : suxen_drol 233 for (j = 63; j > 0 && matrix[scan_tables[0][j - 1]] == last; j--);
655 : Isibaar 3
656 : edgomez 195 for (i = 0; i <= j; i++) {
657 : Isibaar 3 BitstreamPutBits(bs, matrix[scan_tables[0][i]], 8);
658 :     }
659 :    
660 : edgomez 195 if (j < 63) {
661 : Isibaar 3 BitstreamPutBits(bs, 0, 8);
662 :     }
663 :     }
664 :    
665 :    
666 :     /*
667 :     write vol header
668 :     */
669 : edgomez 195 void
670 :     BitstreamWriteVolHeader(Bitstream * const bs,
671 :     const MBParam * pParam,
672 :     const FRAMEINFO * frame)
673 : Isibaar 3 {
674 :     // video object_start_code & vo_id
675 : edgomez 195 BitstreamPad(bs);
676 : Isibaar 3 BitstreamPutBits(bs, VO_START_CODE, 27);
677 : edgomez 195 BitstreamPutBits(bs, 0, 5);
678 : Isibaar 3
679 :     // video_object_layer_start_code & vol_id
680 :     BitstreamPutBits(bs, VOL_START_CODE, 28);
681 :     BitstreamPutBits(bs, 0, 4);
682 :    
683 : edgomez 195 BitstreamPutBit(bs, 0); // random_accessible_vol
684 :     BitstreamPutBits(bs, 0, 8); // video_object_type_indication
685 :     BitstreamPutBit(bs, 0); // is_object_layer_identified (0=not given)
686 :     BitstreamPutBits(bs, 1, 4); // aspect_ratio_info (1=1:1)
687 : suxen_drol 164
688 : chl 387 BitstreamPutBit(bs, 1); // vol_control_parameters
689 :     BitstreamPutBits(bs, 1, 2); // chroma_format 1="4:2:0"
690 :    
691 : edgomez 487 BitstreamPutBit(bs, 1); // low_delay
692 :    
693 : chl 387 BitstreamPutBit(bs, 0); // vbv_parameters (0=not given)
694 : suxen_drol 164
695 : edgomez 195 BitstreamPutBits(bs, 0, 2); // video_object_layer_shape (0=rectangular)
696 : Isibaar 3
697 :     WRITE_MARKER();
698 : edgomez 195
699 : edgomez 487 /*
700 :     * time_increment_resolution; ignored by current decore versions
701 :     * eg. 2fps res=2 inc=1
702 :     * 25fps res=25 inc=1
703 :     * 29.97fps res=30000 inc=1001
704 : edgomez 195 */
705 : suxen_drol 163 BitstreamPutBits(bs, pParam->fbase, 16);
706 : Isibaar 3
707 : edgomez 487
708 : Isibaar 3 WRITE_MARKER();
709 :    
710 : suxen_drol 241 BitstreamPutBit(bs, 1); // fixed_vop_rate = 1
711 :     BitstreamPutBits(bs, pParam->fincr, log2bin(pParam->fbase)); // fixed_vop_time_increment
712 : Isibaar 3
713 :     WRITE_MARKER();
714 : edgomez 195 BitstreamPutBits(bs, pParam->width, 13); // width
715 : Isibaar 3 WRITE_MARKER();
716 : edgomez 195 BitstreamPutBits(bs, pParam->height, 13); // height
717 : Isibaar 3 WRITE_MARKER();
718 : edgomez 195
719 :     BitstreamPutBit(bs, frame->global_flags & XVID_INTERLACING); // interlace
720 : Isibaar 3 BitstreamPutBit(bs, 1); // obmc_disable (overlapped block motion compensation)
721 :     BitstreamPutBit(bs, 0); // sprite_enable
722 :     BitstreamPutBit(bs, 0); // not_in_bit
723 :    
724 :     // quant_type 0=h.263 1=mpeg4(quantizer tables)
725 : suxen_drol 136 BitstreamPutBit(bs, pParam->m_quant_type);
726 : edgomez 195
727 :     if (pParam->m_quant_type) {
728 : Isibaar 4 BitstreamPutBit(bs, get_intra_matrix_status()); // load_intra_quant_mat
729 : edgomez 195 if (get_intra_matrix_status()) {
730 : Isibaar 4 bs_put_matrix(bs, get_intra_matrix());
731 : Isibaar 3 }
732 :    
733 : edgomez 195 BitstreamPutBit(bs, get_inter_matrix_status()); // load_inter_quant_mat
734 :     if (get_inter_matrix_status()) {
735 : Isibaar 4 bs_put_matrix(bs, get_inter_matrix());
736 : Isibaar 3 }
737 :    
738 :     }
739 :    
740 :     BitstreamPutBit(bs, 1); // complexity_estimation_disable
741 :     BitstreamPutBit(bs, 1); // resync_marker_disable
742 :     BitstreamPutBit(bs, 0); // data_partitioned
743 :     BitstreamPutBit(bs, 0); // scalability
744 :     }
745 :    
746 :    
747 :     /*
748 :     write vop header
749 :    
750 :     NOTE: doesnt handle bother with time_base & time_inc
751 :     time_base = n seconds since last resync (eg. last iframe)
752 :     time_inc = nth of a second since last resync
753 :     (decoder uses these values to determine precise time since last resync)
754 :     */
755 : edgomez 195 void
756 :     BitstreamWriteVopHeader(Bitstream * const bs,
757 :     const MBParam * pParam,
758 : suxen_drol 229 const FRAMEINFO * frame,
759 :     int vop_coded)
760 : Isibaar 3 {
761 : suxen_drol 152 uint32_t i;
762 : chl 387
763 : edgomez 195 BitstreamPad(bs);
764 :     BitstreamPutBits(bs, VOP_START_CODE, 32);
765 : Isibaar 3
766 : edgomez 195 BitstreamPutBits(bs, frame->coding_type, 2);
767 :    
768 : Isibaar 3 // time_base = 0 write n x PutBit(1), PutBit(0)
769 : edgomez 195 for (i = 0; i < frame->seconds; i++) {
770 : suxen_drol 152 BitstreamPutBit(bs, 1);
771 :     }
772 :     BitstreamPutBit(bs, 0);
773 : Isibaar 3
774 :     WRITE_MARKER();
775 :    
776 :     // time_increment: value=nth_of_sec, nbits = log2(resolution)
777 : edgomez 195 BitstreamPutBits(bs, frame->ticks, log2bin(pParam->fbase));
778 : Isibaar 3
779 :     WRITE_MARKER();
780 :    
781 : suxen_drol 229 if (!vop_coded) {
782 :     BitstreamPutBits(bs, 0, 1);
783 :     return;
784 :     }
785 :    
786 : edgomez 195 BitstreamPutBits(bs, 1, 1); // vop_coded
787 : Isibaar 3
788 : suxen_drol 163 if (frame->coding_type == P_VOP)
789 : suxen_drol 136 BitstreamPutBits(bs, frame->rounding_type, 1);
790 : Isibaar 3
791 : edgomez 195 BitstreamPutBits(bs, 0, 3); // intra_dc_vlc_threshold
792 :    
793 :     if (frame->global_flags & XVID_INTERLACING) {
794 :     BitstreamPutBit(bs, 1); // top field first
795 :     BitstreamPutBit(bs, 0); // alternate vertical scan
796 : h 69 }
797 :    
798 : edgomez 195 BitstreamPutBits(bs, frame->quant, 5); // quantizer
799 :    
800 : suxen_drol 136 if (frame->coding_type != I_VOP)
801 : edgomez 195 BitstreamPutBits(bs, frame->fcode, 3); // forward_fixed_code
802 : suxen_drol 152
803 :     if (frame->coding_type == B_VOP)
804 : edgomez 195 BitstreamPutBits(bs, frame->bcode, 3); // backward_fixed_code
805 : suxen_drol 152
806 : Isibaar 3 }

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4