[svn] / branches / dev-api-3 / xvidcore / src / bitstream / bitstream.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-3/xvidcore/src/bitstream/bitstream.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 619 - (view) (download)

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

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