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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.28.2.3 - (view) (download)

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

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