[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.29 - (view) (download)

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

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