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