1 /*
2 * parse.c
3 *
4 * Copyright (C) Charles 'Buck' Krasic - April 2000
5 * Copyright (C) Erik Walthinsen - April 2000
6 *
7 * This file is part of libdv, a free DV (IEC 61834/SMPTE 314M)
8 * codec.
9 *
10 * libdv is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser Public License as published by
12 * the Free Software Foundation; either version 2.1, or (at your
13 * option) any later version.
14 *
15 * libdv is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser Public License
21 * along with libdv; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * The libdv homepage is http://libdv.sourceforge.net/.
25 */
26
27 /** @file
28 * @ingroup parser
29 * @brief Implementation for @link parser Video Parser @endlink
30 */
31
32 /** @weakgroup parser Video Parser
33 *
34 * The video parser is the front end of the video decoder. From byte
35 * sequences (<a href="glossary.html#glossary-dif-block">DIF *
36 * blocks</a>) the parser constructs structures for DV video headers
37 * and video segments. These structures become the input to the back
38 * end which does the steps of the hybrid (lossless variable length
39 * coding + lossy transform coding) video decompression.
40 *
41 * @{
42 */
43
44 #if HAVE_CONFIG_H
45 # include <config.h>
46 #endif
47
48 #include <string.h>
49
50 #include "util.h"
51 #include "dv.h"
52 #include "vlc.h"
53 #include "audio.h"
54 #include "parse.h"
55
56 #define STRICT_SYNTAX 0
57 #define VLC_BOUNDS_CHECK 0
58
59 #define PARSE_VLC_TRACE 0
60
61 #ifdef __GNUC__
62 #if PARSE_VLC_TRACE
63 #define vlc_trace(format,args...) fprintf(stdout,format,##args)
64 #else
65 #define vlc_trace(format,args...)
66 #endif /* PARSE_VLC_TRACE */
67 #else
vlc_trace(char * format,...)68 static inline void vlc_trace(char *format, ...)
69 {
70 #if PARSE_VLC_TRACE
71 va_list argp;
72 va_start(argp, format);
73 vfprintf(stdout, format, argp);
74 va_end(argp);
75 #endif /* PARSE_VLC_TRACE */
76 }
77 #endif /* __GNUC__ */
78
79 /* Assign coefficient in zigzag order without indexing multiply */
80 #define ZERO_MULT_ZIGZAG 1
81 #if ZERO_MULT_ZIGZAG
82 #define SET_COEFF(COEFFS,REORDER,VALUE) \
83 (*((dv_coeff_t *)(((uint8_t *)(COEFFS)) + *(REORDER)++)) = (VALUE))
84 #else
85 #define SET_COEFF(COEFFS,REORDER,VALUE) COEFFS[*REORDER++] = VALUE
86 #endif
87
88 int dv_parse_bit_start[6] = { 4*8+12, 18*8+12, 32*8+12, 46*8+12, 60*8+12, 70*8+12 };
89 int dv_parse_bit_end[6] = { 18*8, 32*8, 46*8, 60*8, 70*8, 80*8 };
90
91 int dv_super_map_vertical[5] = { 2, 6, 8, 0, 4 };
92 int dv_super_map_horizontal[5] = { 2, 1, 3, 0, 4 };
93
94 static int8_t dv_88_reorder_prime[64] = {
95 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
96 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
97 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
98 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
99 };
100
101 int8_t dv_reorder[2][64] = {
102 { 0 },
103 {
104 0, 32, 1, 33, 8, 40, 2, 34, 9, 41, 16, 48, 24, 56, 17, 49,
105 10, 42, 3, 35, 4, 36, 11, 43, 18, 50, 25, 57, 26, 58, 19, 51,
106 12, 44, 5, 37, 6, 38, 13, 45, 20, 52, 27, 59, 28, 60, 21, 53,
107 14, 46, 7, 39, 15, 47, 22, 54, 29, 61, 30, 62, 23, 55, 31, 63 }
108 };
109
110 #if HAVE_LIBPOPT
111 /* ---------------------------------------------------------------------------
112 */
113 static void
dv_video_popt_callback(poptContext con,enum poptCallbackReason reason,const struct poptOption * opt,const char * arg,const void * data)114 dv_video_popt_callback(poptContext con, enum poptCallbackReason reason,
115 const struct poptOption * opt, const char * arg, const void * data)
116 {
117 dv_video_t *video = (dv_video_t *)data;
118
119 switch(video->arg_block_quality) {
120 case 1:
121 video->quality |= DV_QUALITY_DC;
122 break;
123 case 2:
124 video->quality |= DV_QUALITY_AC_1;
125 break;
126 case 3:
127 video->quality |= DV_QUALITY_AC_2;
128 break;
129 default:
130 dv_opt_usage(con, video->option_table, DV_VIDEO_OPT_BLOCK_QUALITY);
131 break;
132 } /* switch */
133 if(!video->arg_monochrome) {
134 video->quality |= DV_QUALITY_COLOR;
135 } /* if */
136
137 } /* dv_video_popt_callback */
138 #endif /* HAVE_LIBPOPT */
139
140 /* ---------------------------------------------------------------------------
141 */
142 dv_video_t *
dv_video_new(void)143 dv_video_new(void)
144 {
145 dv_video_t *result;
146
147 result = (dv_video_t *)calloc(1,sizeof(dv_video_t));
148 if(!result) goto noopt;
149
150 result->arg_block_quality = 3; /* Default is best quality */
151
152 #if HAVE_LIBPOPT
153 result->option_table[DV_VIDEO_OPT_BLOCK_QUALITY] = (struct poptOption){
154 longName: "quality",
155 shortName: 'q',
156 argInfo: POPT_ARG_INT,
157 arg: &result->arg_block_quality,
158 argDescrip: "(1|2|3)",
159 descrip: "video quality level (coeff. parsing):"
160 " 1=DC and no ACs,"
161 " 2=DC and single-pass for ACs ,"
162 " 3=DC and multi-pass for ACs [default]",
163 }; /* block quality */
164
165 result->option_table[DV_VIDEO_OPT_MONOCHROME] = (struct poptOption){
166 longName: "monochrome",
167 shortName: 'm',
168 arg: &result->arg_monochrome,
169 descrip: "skip decoding of color blocks",
170 }; /* monochrome */
171
172 result->option_table[DV_VIDEO_OPT_CALLBACK] = (struct poptOption){
173 argInfo: POPT_ARG_CALLBACK|POPT_CBFLAG_POST,
174 arg: dv_video_popt_callback,
175 descrip: (char *)result, /* data passed to callback */
176 }; /* callback */
177 #else
178 result->quality = DV_QUALITY_BEST;
179 #endif /* HAVE_LIBPOPT */
180
181 noopt:
182 return(result);
183 } /* dv_video_new */
184
185 /* ---------------------------------------------------------------------------
186 */
187 void
dv_parse_init(void)188 dv_parse_init(void) {
189 int i;
190 for(i=0;i<64;i++) {
191 #if (!ARCH_X86) && (!ARCH_X86_64)
192 dv_reorder[DV_DCT_88][i] = ((dv_88_reorder_prime[i] / 8) * 8) + (dv_88_reorder_prime[i] % 8);
193 #else
194 dv_reorder[DV_DCT_88][i] = ((dv_88_reorder_prime[i] % 8) * 8) + (dv_88_reorder_prime[i] / 8);
195 #endif
196 } /* for */
197 for(i=0;i<64;i++) {
198 #if ZERO_MULT_ZIGZAG
199 dv_reorder[DV_DCT_88][i] = (dv_reorder[DV_DCT_88][i]) * sizeof(dv_coeff_t);
200 dv_reorder[DV_DCT_248][i] = (dv_reorder[DV_DCT_248][i]) * sizeof(dv_coeff_t);
201 #endif
202 } /* for */
203 } /* dv_parse_init */
204
205 /* ---------------------------------------------------------------------------
206 * Scan the blocks of a macroblock. We're looking to find the next
207 * block from which unused space was borrowed
208 */
209 static inline int
dv_find_mb_unused_bits(dv_macroblock_t * mb,dv_block_t ** lender)210 dv_find_mb_unused_bits(dv_macroblock_t *mb, dv_block_t **lender) {
211 int b;
212
213 for(b=0; b<6; b++) {
214 if((mb->b[b].eob) && /* an incomplete block can only "borrow" bits
215 * from other blocks that are themselves
216 * already completely decoded */
217 (mb->b[b].end > mb->b[b].offset) && /* the lender must have unused bits */
218 (!mb->b[b].mark)) { /* the lender musn't already be lending... */
219 mb->b[b].mark = TRUE;
220 *lender = &mb->b[b];
221 return(TRUE);
222 } /* if */
223 } /* for b */
224 return(FALSE);
225 } /* dv_find_mb_unused_bits */
226
227 /* ---------------------------------------------------------------------------
228 * After parsing vlcs from borrowed space, we must clear the trail of
229 * marks we used to track lenders. found_vlc indicates whether the
230 * scanning process successfully found a complete vlc. If it did,
231 * then we update all blocks that lent bits as having no bits left.
232 * If so, the last block gets fixed in the caller.
233 */
234 static void
dv_clear_mb_marks(dv_macroblock_t * mb,int found_vlc)235 dv_clear_mb_marks(dv_macroblock_t *mb, int found_vlc) {
236 dv_block_t *bl; int b;
237
238 for(b=0,bl=mb->b;
239 b<6;
240 b++,bl++) {
241 if(bl->mark) {
242 bl->mark = FALSE;
243 if(found_vlc) bl->offset = bl->end;
244 }
245 }
246 } /* dv__clear_mb_marks */
247
248 /* ---------------------------------------------------------------------------
249 * For pass 3, we scan all blocks of a video segment for unused bits
250 */
251 static int
dv_find_vs_unused_bits(dv_videosegment_t * seg,dv_block_t ** lender)252 dv_find_vs_unused_bits(dv_videosegment_t *seg, dv_block_t **lender) {
253 dv_macroblock_t *mb;
254 int m;
255
256 for(m=0,mb=seg->mb;
257 m<5;
258 m++,mb++) {
259 if((mb->eob_count == 6) && /* We only borrow bits from macroblocks that are themselves complete */
260 dv_find_mb_unused_bits(mb,lender))
261 return(TRUE);
262 } /* for */
263 return(FALSE);
264 } /* dv_find_vs_unused_bits */
265
266 /* ---------------------------------------------------------------------------
267 * For pass 3, the trail of lenders can span the whole video segment
268 */
269 static void
dv_clear_vs_marks(dv_videosegment_t * seg,int found_vlc)270 dv_clear_vs_marks(dv_videosegment_t *seg,int found_vlc) {
271 dv_macroblock_t *mb;
272 int m;
273
274 for(m=0,mb=seg->mb;
275 m<5;
276 m++,mb++)
277 dv_clear_mb_marks(mb,found_vlc);
278 } /* dv_clear_vs_marks */
279
280 /* ---------------------------------------------------------------------------
281 * For passes 2 and 3, vlc data that didn't fit in the area of a block
282 * are put in space borrowed from other blocks. Pass 2 borrows from
283 * blocks of the same macroblock. Pass 3 uses space from blocks of
284 * other macroblocks of the videosegment.
285 */
286 static int
dv_find_spilled_vlc(dv_videosegment_t * seg,dv_macroblock_t * mb,dv_block_t ** bl_lender,int pass)287 dv_find_spilled_vlc(dv_videosegment_t *seg, dv_macroblock_t *mb, dv_block_t **bl_lender, int pass) {
288 dv_vlc_t vlc;
289 dv_block_t *bl_new_lender;
290 int found_vlc, found_bits;
291 int bits_left, found_bits_left;
292 int save_offset = 0;
293 int broken_vlc = 0;
294 bitstream_t *bs;
295
296 bs = seg->bs;
297 if((bits_left = (*bl_lender)->end - (*bl_lender)->offset))
298 broken_vlc=bitstream_get(bs,bits_left);
299 found_vlc = FALSE;
300 found_bits = dv_find_mb_unused_bits(mb,&bl_new_lender);
301 if(!found_bits && pass != 1)
302 found_bits = dv_find_vs_unused_bits(seg,&bl_new_lender);
303 while(found_bits && (!found_vlc)) {
304 bitstream_seek_set(bs, bl_new_lender->offset);
305 found_bits_left = bl_new_lender->end - bl_new_lender->offset;
306 if(bits_left) /* prepend broken vlc if there is one */
307 bitstream_unget(bs, broken_vlc, bits_left);
308 dv_peek_vlc(bs, found_bits_left + bits_left, &vlc);
309 if(vlc.len >= 0) {
310 /* found a vlc, set things up to return to the main coeff loop */
311 save_offset = bl_new_lender->offset - bits_left;
312 found_vlc = TRUE;
313 } else if(vlc.len == VLC_NOBITS) {
314 /* still no vlc */
315 bits_left += found_bits_left;
316 broken_vlc = bitstream_get(bs, bits_left);
317 if(pass == 1)
318 found_bits = dv_find_mb_unused_bits(mb,&bl_new_lender);
319 else if(!(found_bits = dv_find_mb_unused_bits(mb,&bl_new_lender)))
320 found_bits = dv_find_vs_unused_bits(seg,&bl_new_lender);
321 } else {
322 if(pass == 1) dv_clear_mb_marks(mb,found_vlc);
323 else dv_clear_vs_marks(seg,found_vlc);
324 return(-1);
325 } /* else */
326 } /* while */
327 if(pass == 1) dv_clear_mb_marks(mb,found_vlc);
328 else dv_clear_vs_marks(seg,found_vlc);
329 if(found_vlc) {
330 bl_new_lender->offset = save_offset; /* fixup offset clobbered by clear marks */
331 *bl_lender = bl_new_lender;
332 }
333 return(found_vlc);
334 } /* dv_find_spilled_vlc */
335
336
337 /* ---------------------------------------------------------------------------
338 */
339 int
dv_parse_ac_coeffs(dv_videosegment_t * seg)340 dv_parse_ac_coeffs(dv_videosegment_t *seg) {
341 dv_vlc_t vlc;
342 int m, b, pass;
343 int bits_left;
344 int vlc_error;
345 int8_t **reorder, *reorder_sentinel;
346 dv_coeff_t *coeffs;
347 dv_macroblock_t *mb;
348 dv_block_t *bl, *bl_bit_source;
349 bitstream_t *bs;
350
351 bs = seg->bs;
352 /* Phase 2: do the 3 pass AC vlc decode */
353 vlc_error = FALSE;
354 for (pass=1;pass<3;pass++) {
355 vlc_trace("P%d",pass);
356 if((pass == 2) && vlc_error) break;
357 for (m=0,mb=seg->mb;
358 m<5;
359 m++,mb++) {
360 /* if(vlc_error) goto abort_segment; */
361 vlc_trace("\nM%d",m);
362 if((pass == 1) && mb->vlc_error) continue;
363 for (b=0,bl=mb->b;
364 b<6;
365 b++,bl++) {
366 if(bl->eob) continue;
367 coeffs = bl->coeffs;
368 vlc_trace("\nB%d",b);
369 bitstream_seek_set(bs,bl->offset);
370 reorder = &bl->reorder;
371 reorder_sentinel = bl->reorder_sentinel;
372 bl_bit_source = bl;
373 /* Main coeffient parsing loop */
374 while(1) {
375 bits_left = bl_bit_source->end - bl_bit_source->offset;
376 dv_peek_vlc(bs,bits_left,&vlc);
377 if(vlc.run < 0) goto bh;
378 /* complete, valid vlc found */
379 vlc_trace("(%d,%d,%d)",vlc.run,vlc.amp,vlc.len);
380 bl_bit_source->offset += vlc.len;
381 bitstream_flush(bs,vlc.len);
382 *reorder += vlc.run;
383 if((*reorder) < reorder_sentinel) {
384 SET_COEFF(coeffs,(*reorder),vlc.amp);
385 } else {
386 vlc_trace("! vlc code overran coeff block");
387 goto vlc_error;
388 } /* else */
389 continue;
390 bh:
391 if(vlc.amp == 0) {
392 /* found eob vlc */
393 vlc_trace("#");
394 /* EOb -- zero out the rest of block */
395 *reorder = reorder_sentinel;
396 bl_bit_source->offset += 4;
397 bitstream_flush(bs,4);
398 bl->eob = 1;
399 mb->eob_count++;
400 break;
401 } else if(vlc.len == VLC_NOBITS) {
402 bl_bit_source->mark = TRUE;
403 switch(dv_find_spilled_vlc(seg,mb,&bl_bit_source,pass)) {
404 case 1: /* found: keep parsing */
405 break;
406 case 0: /* not found: move on to next block */
407 if(pass==1) goto mb_done;
408 else goto seg_done;
409 break;
410 case -1:
411 goto vlc_error;
412 break;
413 } /* switch */
414 } else if(vlc.len == VLC_ERROR) {
415 goto vlc_error;
416 } /* else (used == ?) */
417 } /* while !bl->eob */
418 goto bl_done;
419 vlc_error:
420 vlc_trace("X\n");
421 vlc_error = TRUE;
422 if(pass == 1) goto mb_done;
423 else goto abort_segment;
424 bl_done:
425 #if PARSE_VLC_TRACE
426 if((bits_left = bl->end - bl->offset)) {
427 int x;
428 bitstream_seek_set(bs,bl->offset);
429 vlc_trace("\n\tunused bits:\n\t");
430 for(x=bits_left-1;x>=0;x--)
431 vlc_trace("%s", (bitstream_get(bs,1)) ? "1" : "0");
432 } else { vlc_trace("\n\tno unused bits"); }
433 #endif /* PARSE_VLC_TRACE */
434 ; } /* for b */
435 mb_done:
436 ; } /* for m */
437 vlc_trace("\n");
438 } /* for pass */
439 vlc_trace("Segment OK. ");
440 goto seg_done;
441 abort_segment:
442 vlc_trace("Segment aborted. ");
443 seg_done:
444 #if 0
445 /* zero out remaining coeffs */
446 x = 0;
447 for(m=0,mb=seg->mb;
448 m<5;
449 m++,mb++) {
450 for (b=0,bl=mb->b;
451 b<6;
452 b++,bl++) {
453 coeffs = bl->coeffs;
454 reorder = &bl->reorder;
455 reorder_sentinel = bl->reorder_sentinel;
456 while((*reorder) < reorder_sentinel) {
457 SET_COEFF(coeffs,(*reorder),0);
458 x++;
459 } /* while */
460 } /* for b */
461 } /* for m */
462 vlc_trace("%d coeffs lost\n", x);
463 return(x);
464 #else
465 return(0);
466 #endif
467 #if 0
468 fatal_vlc_error:
469 vlc_trace("\n\nOffset %d\n", offset);
470 vlc_trace("DIF Block:\n");
471 for(x=0; x<dv_parse_bytes[b]; x++) {
472 if(!(x%10)) vlc_trace("\n");
473 print_byte(data[(m*80)+dv_parse_blockstart[b]+x]);
474 vlc_trace(" ");
475 } /* for */
476 vlc_trace("\n");
477 exit(0);
478 #endif
479 } /* dv_parse_ac_coeffs */
480
481 /* ---------------------------------------------------------------------------
482 */
483 void
484 dv_parse_ac_coeffs_pass0(bitstream_t *bs,
485 dv_macroblock_t *mb,
486 dv_block_t *bl);
487
488 #if (!ARCH_X86) && (!ARCH_X86_64)
489 /* ---------------------------------------------------------------------------
490 */
491 __inline__ void
dv_parse_ac_coeffs_pass0(bitstream_t * bs,dv_macroblock_t * mb,dv_block_t * bl)492 dv_parse_ac_coeffs_pass0(bitstream_t *bs,
493 dv_macroblock_t *mb,
494 dv_block_t *bl) {
495 dv_vlc_t vlc;
496 int bits_left;
497 uint32_t bits;
498
499 /* vlc_trace("\nB%d",b); */
500 /* Main coeffient parsing loop */
501 memset(&bl->coeffs[1],'\0',sizeof(bl->coeffs)-sizeof(bl->coeffs[0]));
502 while(1) {
503 bits_left = bl->end - bl->offset;
504 bits = bitstream_show(bs,16);
505 if(bits_left >= 16)
506 __dv_decode_vlc(bits, &vlc);
507 else
508 dv_decode_vlc(bits, bits_left,&vlc);
509 if(vlc.run < 0) break;
510 /* complete, valid vlc found */
511 vlc_trace("(%d,%d,%d)",vlc.run,vlc.amp,vlc.len);
512 bl->offset += vlc.len;
513 bitstream_flush(bs,vlc.len);
514 bl->reorder += vlc.run;
515 SET_COEFF(bl->coeffs,bl->reorder,vlc.amp);
516 } /* while */
517 if(vlc.amp == 0) {
518 /* found eob vlc */
519 vlc_trace("#");
520 /* EOb -- zero out the rest of block */
521 bl->reorder = bl->reorder_sentinel;
522 bl->offset += 4;
523 bitstream_flush(bs,4);
524 bl->eob = 1;
525 mb->eob_count++;
526 } else if(vlc.len == VLC_ERROR) {
527 vlc_trace("X\n");
528 mb->vlc_error = TRUE;
529 } /* else */
530 #if PARSE_VLC_TRACE
531 if((bits_left = bl->end - bl->offset)) {
532 int x;
533 bitstream_seek_set(bs,bl->offset);
534 vlc_trace("\n\tunused bits:\n\t");
535 for(x=bits_left-1;x>=0;x--)
536 vlc_trace("%s", (bitstream_get(bs,1)) ? "1" : "0");
537 } else { vlc_trace("\n\tno unused bits"); }
538 #endif /* PARSE_VLC_TRACE */
539 vlc_trace("\n");
540 } /* dv_parse_ac_coeffs_pass0 */
541 #endif
542
543 /* ---------------------------------------------------------------------------
544 * DV requires vlc decode of AC coefficients for each block in three passes:
545 * Pass1 : decode coefficient vlc bits from their own block's area
546 * Pass2 : decode coefficient vlc bits spilled into areas of other blocks of the same macroblock
547 * Pass3 : decode coefficient vlc bits spilled into other macroblocks of the same video segment
548 *
549 * What to do about VLC errors? This is tricky.
550 *
551 * The most conservative is to assume that any further spilled data is suspect.
552 * So, on pass 1, a VLC error means do the rest, and skip passes 2 & 3
553 * On passes 2 & 3, just abort. This seems to drop a lot more coefficients, 21647
554 * in a single frame, that more tolerant aproaches.
555 */
556 #if (!ARCH_X86) && (!ARCH_X86_64)
557 int
dv_parse_video_segment(dv_videosegment_t * seg,unsigned int quality)558 dv_parse_video_segment(dv_videosegment_t *seg, unsigned int quality) {
559 int m, b;
560 int mb_start;
561 int dc;
562 dv_macroblock_t *mb;
563 dv_block_t *bl;
564 bitstream_t *bs;
565 unsigned int n_blocks;
566
567 vlc_trace("S[%d,%d]\n", seg->i,seg->k);
568 /* Phase 1: initialize data structures, and get the DC */
569 bs = seg->bs;
570
571 if (quality & DV_QUALITY_COLOR)
572 n_blocks = 6;
573 else
574 n_blocks = 4;
575
576 for(m=0,mb=seg->mb,mb_start=0;
577 m<5;
578 m++,mb++,mb_start+=(80*8)) {
579 #if STRICT_SYNTAX
580 bitstream_seek_set(bs,mb_start);
581 g_return_val_if_fail(((bitstream_get(bs,3) == DV_SCT_VIDEO)),6*64); /* SCT */
582 bitstream_flush(bs,5);
583
584 g_return_val_if_fail((bitstream_get(bs,4) == seg->i),6*64);
585 g_return_val_if_fail((bitstream_get(bs,1) == DV_FSC_0),6*64);
586 bitstream_flush(bs,3);
587
588 bitstream_flush(bs,8); /* DBN -- could check this */
589 mb->sta = bitstream_get(bs,4);
590 #else
591 bitstream_seek_set(bs,mb_start+28);
592 #endif
593 /* first get the macroblock-wide data */
594 mb->qno = bitstream_get(bs,4);
595 mb->vlc_error = 0;
596 mb->eob_count = 0;
597 mb->i = (seg->i + dv_super_map_vertical[m]) % (seg->isPAL?12:10);
598 mb->j = dv_super_map_horizontal[m];
599 mb->k = seg->k;
600 if ((quality & DV_QUALITY_AC_MASK) == DV_QUALITY_DC) {
601 /* DC only */
602 for(b=0,bl=mb->b;
603 b < n_blocks;
604 b++,bl++) {
605 memset(bl->coeffs, 0, sizeof(bl->coeffs));
606 dc = bitstream_get(bs,9); /* DC coefficient (twos complement) */
607 if(dc > 255) dc -= 512;
608 bl->coeffs[0] = dc;
609 vlc_trace("DC [%d,%d,%d,%d] = %d\n",mb->i,mb->j,mb->k,b,dc);
610 bl->dct_mode = bitstream_get(bs,1);
611 bl->class_no = bitstream_get(bs,2);
612 bitstream_seek_set(bs, mb_start + dv_parse_bit_end[b]);
613 } /* for b */
614 } else {
615 /* quality is DV_QUALITY_AC_1 or DV_QUALITY_AC_2 */
616 for(b=0,bl=mb->b;
617 b < n_blocks;
618 b++,bl++) {
619 /* Pass 0, read bits from individual blocks */
620 /* Get DC coeff, mode, and class from start of block */
621 dc = bitstream_get(bs,9); /* DC coefficient (twos complement) */
622 if(dc > 255) dc -= 512;
623 bl->coeffs[0] = dc;
624 vlc_trace("DC [%d,%d,%d,%d] = %d\n",mb->i,mb->j,mb->k,b,dc);
625 bl->dct_mode = bitstream_get(bs,1);
626 bl->class_no = bitstream_get(bs,2);
627 bl->eob=0;
628 bl->offset= mb_start + dv_parse_bit_start[b];
629 bl->end= mb_start + dv_parse_bit_end[b];
630 bl->reorder = &dv_reorder[bl->dct_mode][1];
631 bl->reorder_sentinel = bl->reorder + 63;
632 dv_parse_ac_coeffs_pass0(bs,mb,bl);
633 bitstream_seek_set(bs,bl->end);
634 } /* for b */
635 } /* if quality */
636 } /* for m */
637 /* Phase 2: do the 3 pass AC vlc decode */
638 if ((quality & DV_QUALITY_AC_MASK) == DV_QUALITY_AC_2)
639 return(dv_parse_ac_coeffs(seg));
640 else
641 return 0;
642 } /* dv_parse_video_segment */
643 #endif
644
645 /* ---------------------------------------------------------------------------
646 */
647 static void
dv_parse_ssyb(dv_decoder_t * dv,const uint8_t * buffer)648 dv_parse_ssyb (dv_decoder_t *dv, const uint8_t *buffer) {
649 int i, j, k,
650 #if 0
651 got13 = 0, got62 = 0, got63 = 0,
652 #endif
653 pack;
654
655 /*
656 * reset ssyb structure first
657 */
658 dv -> ssyb_next = 0;
659 memset (dv -> ssyb_pack, 0xff, sizeof (dv -> ssyb_pack));
660
661 for (k = 0, buffer += 80; k < 2; ++k, buffer += ((148 * 80) + (5 * 80 * 150))) {
662 for (i = 0/*, buffer += 80*/; i < 2; ++i, buffer += 80) {
663 for (j = 0; j < 6; ++j) {
664 if ((pack = buffer [3 + 3 + (j * 8)]) != 0xff && dv -> ssyb_next < 45) {
665 dv -> ssyb_pack [pack] = dv -> ssyb_next;
666 memcpy (dv -> ssyb_data [dv -> ssyb_next], &buffer [7 + (j * 8)], 4);
667 dv -> ssyb_next++;
668 #if 0
669 switch (pack) {
670 case 0x13:
671 if (!got13) {
672 got13 = 1;
673 fprintf (stderr, "%02d:%02d:%02d.%02d ",
674 ((buffer [3 + 7 + (j * 8)] >> 4) & 0x03) * 10 +
675 (buffer [3 + 7 + (j * 8)] & 0x0f),
676 ((buffer [3 + 6 + (j * 8)] >> 4) & 0x07) * 10 +
677 (buffer [3 + 6 + (j * 8)] & 0x0f),
678 ((buffer [3 + 5 + (j * 8)] >> 4) & 0x07) * 10 +
679 (buffer [3 + 5 + (j * 8)] & 0x0f),
680 ((buffer [3 + 4 + (j * 8)] >> 4) & 0x03) * 10 +
681 (buffer [3 + 4 + (j * 8)] & 0x0f));
682 }
683 break;
684 case 0x62:
685 if (!got62) {
686 int year;
687
688 year = buffer [3 + 7 + (j * 8)];
689 year = (year & 0x0f) + 10 * ((year >> 4) & 0x0f);
690 year += (year < 25) ? 2000 : 1900;
691
692 got62 = 1;
693 fprintf (stderr, "%04d-%02d-%02d ",
694 year,
695 ((buffer [3 + 6 + (j * 8)] >> 4) & 0x01) * 10 +
696 (buffer [3 + 6 + (j * 8)] & 0x0f),
697 ((buffer [3 + 5 + (j * 8)] >> 4) & 0x03) * 10 +
698 (buffer [3 + 5 + (j * 8)] & 0x0f));
699 }
700 break;
701 case 0x63:
702 if (!got63) {
703 got63 = 1;
704 fprintf (stderr, "%02d:%02d:%02d\n",
705 ((buffer [3 + 7 + (j * 8)] >> 4) & 0x03) * 10 +
706 (buffer [3 + 7 + (j * 8)] & 0x0f),
707 ((buffer [3 + 6 + (j * 8)] >> 4) & 0x07) * 10 +
708 (buffer [3 + 6 + (j * 8)] & 0x0f),
709 ((buffer [3 + 5 + (j * 8)] >> 4) & 0x07) * 10 +
710 (buffer [3 + 5 + (j * 8)] & 0x0f));
711 }
712 break;
713
714 }
715 #endif
716 #if 0
717 fprintf (stderr,
718 " pack (%02x - %02x - %02x) (%02x,%02x,%02x,%02x,%02x)\n",
719 buffer [3 + 0 + (j * 8)],
720 buffer [3 + 1 + (j * 8)],
721
722 (buffer [3 + 0 + (j * 8)] & 0xf0) | (buffer [3 + 1 + (j * 8)] & 0x0f),
723
724 buffer [3 + 3 + (j * 8)],
725 buffer [3 + 4 + (j * 8)],
726 buffer [3 + 5 + (j * 8)],
727 buffer [3 + 6 + (j * 8)],
728 buffer [3 + 7 + (j * 8)]);
729 #endif
730 }
731 }
732 }
733 }
734 }
735
736 /* ---------------------------------------------------------------------------
737 */
738 static void
dv_parse_vaux(dv_decoder_t * dv,const uint8_t * buffer)739 dv_parse_vaux (dv_decoder_t *dv, const uint8_t *buffer) {
740 int i, j;
741
742 /*
743 * reset vaux structure first
744 */
745 dv -> vaux_next = 0;
746 memset (dv -> vaux_pack, 0xff, sizeof (dv -> vaux_pack));
747 /*
748 * so search thru all 3 vaux packs
749 */
750 for (i = 0, buffer += 240; i < 3; ++i, buffer += 80) {
751 /*
752 * each pack may contain up to 15 packets
753 */
754 for (j = 0; j < 15; j++) {
755 if (buffer [3 + (j * 5)] != 0xff && dv -> vaux_next < 45) {
756 dv -> vaux_pack [buffer [3 + (j * 5)]] = dv -> vaux_next;
757 memcpy (dv -> vaux_data [dv -> vaux_next], &buffer [3 + 1 + (j * 5)], 4);
758 dv -> vaux_next++;
759 #if 0
760 fprintf (stderr,
761 " pack (%02x) (%02x,%02x,%02x,%02x)\n",
762 buffer [3 + 0 + (j * 5)],
763 buffer [3 + 1 + (j * 5)],
764 buffer [3 + 2 + (j * 5)],
765 buffer [3 + 3 + (j * 5)],
766 buffer [3 + 4 + (j * 5)]);
767 #endif
768 }
769 }
770 }
771 }
772
773 /* ---------------------------------------------------------------------------
774 */
775 int
dv_parse_id(bitstream_t * bs,dv_id_t * id)776 dv_parse_id(bitstream_t *bs,dv_id_t *id) {
777 id->sct = bitstream_get(bs,3);
778 bitstream_flush(bs,5);
779 id->dsn = bitstream_get(bs,4);
780 id->fsc = bitstream_get(bs,1);
781 bitstream_flush(bs,3);
782 id->dbn = bitstream_get(bs,8);
783 return 0;
784 } /* dv_parse_id */
785
786 /* ---------------------------------------------------------------------------
787 */
788 void
dv_parse_packs(dv_decoder_t * dv,const uint8_t * buffer)789 dv_parse_packs(dv_decoder_t *dv, const uint8_t *buffer) {
790 dv_parse_ssyb (dv, buffer);
791 /* dv_parse_aaux (dv, buffer); */
792 } /* dv_parse_packs () */
793
794 /* ---------------------------------------------------------------------------
795 */
796 int
dv_parse_header(dv_decoder_t * dv,const uint8_t * buffer)797 dv_parse_header(dv_decoder_t *dv, const uint8_t *buffer) {
798 dv_header_t *header = &dv->header;
799 bitstream_t *bs;
800 dv_id_t id;
801 int prev_system, result = 0;
802
803 if(!(bs = _dv_bitstream_init())) goto no_bitstream;
804 _dv_bitstream_new_buffer(bs,(uint8_t *)buffer,6*80);
805 dv_parse_id(bs,&id);
806 if (id.sct != 0) goto parse_error; /* error, if not header */
807 header->dsf = bitstream_get(bs,1);
808 if (bitstream_get(bs,1) != 0) goto parse_error; /* error, bit incorrect */
809 bitstream_flush(bs,11);
810 header->apt = bitstream_get(bs,3);
811 header->tf1 = bitstream_get(bs,1);
812 bitstream_flush(bs,4);
813 header->ap1 = bitstream_get(bs,3);
814 header->tf2 = bitstream_get(bs,1);
815 bitstream_flush(bs,4);
816 header->ap2 = bitstream_get(bs,3);
817 header->tf3 = bitstream_get(bs,1);
818 bitstream_flush(bs,4);
819 header->ap3 = bitstream_get(bs,3);
820 bitstream_flush_large(bs,576); /* skip rest of DIF block */
821
822 /*
823 * parse vaux data now to check if there is a inconsistanciy between
824 * header->dsf and vaux data for auto mode
825 */
826 dv_parse_vaux (dv, buffer);
827 switch(dv->arg_video_system) {
828 case 0:
829 prev_system = dv->system;
830 dv->system = (header->dsf || (dv_system_50_fields (dv) == 1)) ?
831 e_dv_system_625_50 : e_dv_system_525_60;
832 if (prev_system != dv->system) {
833 if (dv->system == e_dv_system_625_50)
834 result = 1;
835 else
836 result = 2;
837 } /* if */
838 dv->std = ((header->apt) ? e_dv_std_smpte_314m : e_dv_std_iec_61834);
839 break;
840 case 1:
841 /* NTSC */
842 dv->system = e_dv_system_525_60;
843 dv->std = e_dv_std_smpte_314m; /* arbitrary */
844 break;
845 case 2:
846 /* PAL/IEC 68134 */
847 dv->system = e_dv_system_625_50;
848 dv->std = e_dv_std_iec_61834;
849 break;
850 case 3:
851 /* PAL/SMPTE 314M */
852 dv->system = e_dv_system_625_50;
853 dv->std = e_dv_std_smpte_314m;
854 break;
855 } /* switch */
856
857 dv->width = 720;
858 dv->sampling = ((dv->system == e_dv_system_625_50) && (dv->std == e_dv_std_iec_61834)) ? e_dv_sample_420 : e_dv_sample_411;
859 if(dv->system == e_dv_system_625_50) {
860 dv->num_dif_seqs = 12;
861 dv->height = 576;
862 dv->frame_size = 12 * 150 * 80;
863 } else {
864 dv->num_dif_seqs = 10;
865 dv->height = 480;
866 dv->frame_size = 10 * 150 * 80;
867 } /* else */
868
869 dv_parse_id(bs,&id); /* should be SC1 */
870 bitstream_flush_large(bs,616);
871 dv_parse_id(bs,&id); /* should be SC2 */
872 bitstream_flush_large(bs,616);
873
874 dv_parse_id(bs,&id); /* should be VA1 */
875 bitstream_flush_large(bs,616);
876 dv_parse_id(bs,&id); /* should be VA2 */
877 bitstream_flush_large(bs,616);
878 dv_parse_id(bs,&id); /* should be VA3 */
879 bitstream_flush_large(bs,616);
880
881 dv_parse_audio_header(dv, buffer);
882
883 free( bs );
884
885 return(result);
886
887 parse_error:
888 free( bs );
889 no_bitstream:
890 return(-1);
891 } /* dv_parse_header */
892
893 /*@}*/
894