~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/codec/p64/p64dump.cc

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /*
  2  * p64dump.cc --
  3  *
  4  *      FIXME: This file needs a description here.
  5  *
  6  * This code is derived from (but bears little resemblance to)
  7  * the P64 software implementation by the Stanford PVRG group.
  8  * Their copyright applies herein:
  9  *
 10  * Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
 11  * PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
 12  * Group. If you use this software, you agree to the following: This
 13  * program package is purely experimental, and is licensed "as is".
 14  * Permission is granted to use, modify, and distribute this program
 15  * without charge for any purpose, provided this license/ disclaimer
 16  * notice appears in the copies.  No warranty or maintenance is given,
 17  * either expressed or implied.  In no event shall the author(s) be
 18  * liable to you or a third party for any special, incidental,
 19  * consequential, or other damages, arising out of the use or inability
 20  * to use the program for any purpose (or the loss of data), even if we
 21  * have been advised of such possibilities.  Any public reference or
 22  * advertisement of this source code should refer to it as the Portable
 23  * Video Research Group (PVRG) code, and not by any author(s) (or
 24  * Stanford University) name.
 25  */
 26 
 27 #ifndef lint
 28 static const char rcsid[] =
 29     "@(#) $Header: /usr/mash/src/repository/mash/mash-1/codec/p64/p64dump.cc,v 1.7 2003/11/19 19:20:22 aswan Exp $";
 30 #endif
 31 
 32 #include <stdarg.h>
 33 #include <stdio.h>
 34 #include <string.h>
 35 
 36 #ifndef WIN32
 37 #include <sys/param.h>
 38 #include <sys/file.h>
 39 #endif
 40 #include <sys/stat.h>
 41 #include "misc/bsd-endian.h"
 42 #include "codec/p64/p64.h"
 43 #include "codec/p64/p64dump.h"
 44 #include "codec/p64/p64-huff.h"
 45 #include "codec/dct.h"
 46 
 47 
 48 P64Dumper::P64Dumper(int q)
 49 {
 50         dump_quantized_ = q;
 51 }
 52 
 53 P64Dumper::P64Dumper()
 54 {
 55         dump_quantized_ = 0;
 56 }
 57 
 58 #if BYTE_ORDER == LITTLE_ENDIAN
 59 #define HUFFRQ(bs, bb) \
 60  { \
 61         register int t = *bs++; \
 62         bb <<= 16; \
 63         bb |= (t & 0xff) << 8; \
 64         bb |= t >> 8; \
 65 }
 66 #else
 67 #define HUFFRQ(bs, bb) \
 68  { \
 69         bb <<= 16; \
 70         bb |= *bs++; \
 71 }
 72 #endif
 73 
 74 #define MASK(s) ((1 << (s)) - 1)
 75 
 76 #define HUFF_DECODE(bs, ht, nbb, bb, result) { \
 77         register int s__, v__; \
 78  \
 79         if (nbb < 16) { \
 80                 HUFFRQ(bs, bb); \
 81                 nbb += 16; \
 82         } \
 83         s__ = ht.maxlen; \
 84         v__ = (bb >> (nbb - s__)) & MASK(s__); \
 85         s__ = (ht.prefix)[v__]; \
 86         nbb -= (s__ & 0x1f); \
 87         result = s__ >> 5; \
 88  }
 89 
 90 #define GET_BITS(bs, n, nbb, bb, result) \
 91 { \
 92         nbb -= n; \
 93         if (nbb < 0)  { \
 94                 HUFFRQ(bs, bb); \
 95                 nbb += 16; \
 96         } \
 97         (result) = ((bb >> nbb) & MASK(n)); \
 98 }
 99 
100 #define SKIP_BITS(bs, n, nbb, bb) \
101 { \
102         nbb -= n; \
103         if (nbb < 0)  { \
104                 HUFFRQ(bs, bb); \
105                 nbb += 16; \
106         } \
107 }
108 
109 #define DUMPBITS(c) dump_bits(c)
110 
111 void P64Dumper::dump_bits(char c)
112 {
113         int nbits = (bs_ - dbs_) * 16 + dnbb_ - nbb_;
114         int v;
115         printf("%d/", nbits);
116         while (nbits > 16) {
117                 GET_BITS(dbs_, 16, dnbb_, dbb_, v);
118                 printf("%04x", v);
119                 nbits -= 16;
120         }
121         if (nbits > 0) {
122                 GET_BITS(dbs_, nbits, dnbb_, dbb_, v);
123                 if (nbits <= 4)
124                         printf("%01x%c", v, c);
125                 else if (nbits <= 8)
126                         printf("%02x%c", v, c);
127                 else if (nbits <= 12)
128                         printf("%03x%c", v, c);
129                 else
130                         printf("%04x%c", v, c);
131         }
132 }
133 
134 void P64Dumper::err(const char* msg ...) const
135 {
136         va_list ap;
137         va_start(ap, msg);
138         printf("-err: ");
139         vfprintf(stdout, msg, ap);
140         printf(" @g%d m%d %d/%d of %d/%d: %04x %04x %04x %04x|%04x\n",
141                 gob_, mba_,
142                (u_char*)bs_ - (u_char*)ps_, nbb_,
143                (u_char*)es_ - (u_char*)ps_, pebit_,
144                bs_[-4], bs_[-3], bs_[-2], bs_[-1], bs_[0]);
145 }
146 
147 
148 /*
149  * Decode the next block of transform coefficients
150  * from the input stream.
151  */
152 #ifdef INT_64
153 int P64Dumper::parse_block(short* blk, INT_64* mask)
154 #else
155 int P64Dumper::parse_block(short* blk, u_int* mask)
156 #endif
157 {
158 #ifdef INT_64
159         INT_64 m0 = 0;
160 #else
161         u_int m1 = 0, m0 = 0;
162 #endif
163         /*
164          * Cache bit buffer in registers.
165          */
166         register int nbb = nbb_;
167         register int bb = bb_;
168         register short* qt = qt_;
169         register int val = 0, k;
170 
171         if ((mt_ & MT_CBP) == 0) {
172                 int v;
173                 GET_BITS(bs_, 8, nbb, bb, v);
174                 val = v;
175                 if (v == 255)
176                         v = 128;
177                 if (mt_ & MT_INTRA)
178                         v <<= 3;
179                 else
180                         v = qt[v];
181                 blk[0] = v;
182                 k = 1;
183                 m0 |= 1;
184         } else if ((bb >> (nbb - 1)) & 1) {
185                 /*
186                  * In CBP blocks, the first block present must be
187                  * non-empty (otherwise it's mask bit wouldn't
188                  * be set), so the first code cannot be an EOB.
189                  * CCITT optimizes this case by using a huffman
190                  * table equivalent to ht_tcoeff_ but without EOB,
191                  * in which 1 is coded as "1" instead of "11".
192                  * We grab two bits, the first bit is the code
193                  * and the second is the sign.
194                  */
195                 int v;
196                 GET_BITS(bs_, 2, nbb, bb, v);
197                 val = v;
198                 /*FIXME quantize?*/
199                 blk[0] = qt[(v & 1) ? 0xff : 1];
200                 k = 1;
201                 m0 |= 1;
202         } else {
203                 k = 0;
204 #ifndef INT_64
205                 blk[0] = 0;/*FIXME need this because the way we set bits below*/
206 #endif
207         }
208 
209         if (k != 0) {
210                 printf("0:%d ", dump_quantized_? val : blk[0]);
211         }
212         int nc = 0;
213         for (;;) {
214                 int r, v;
215                 HUFF_DECODE(bs_, ht_tcoeff_, nbb, bb, r);
216                 if (r <= 0) {
217                         /* SYM_EOB, SYM_ILLEGAL, or SYM_ESCAPE */
218                         if (r == SYM_ESCAPE) {
219                                 GET_BITS(bs_, 14, nbb, bb, r);
220                                 v = r & 0xff;
221                                 r >>= 8;
222                                 val = v;
223                         } else {
224                                 if (r == SYM_ILLEGAL) {
225                                         bb_ = bb;
226                                         nbb_ = nbb;
227                                         err("illegal symbol in block");
228                                 }
229                                 /* EOB */
230                                 break;
231                         }
232                 } else {
233                         v = (r << 22) >> 27;
234                         r = r & 0x1f;
235                         val = v;
236                 }
237                 k += r;
238                 if (k >= 64) {
239                         bb_ = bb;
240                         nbb_ = nbb;
241                         err("bad run length %d (r %d, v %d)", k, r, v);
242                         break;
243                 }
244                 printf("%d:%d ", k, dump_quantized_? val : qt[v & 0xff]);
245                 r = COLZAG[k++];
246                 blk[r] = qt[v & 0xff];
247                 ++nc;
248 #ifdef INT_64
249                 m0 |= (INT_64)1 << r;
250 #else
251                 /*
252                  * This sets bit "r" if r < 32, otherwise
253                  * it sets bit 0, but this is okay since
254                  * we always set blk[0] FIXME
255                  */
256                 m0 |= 1 << (r & ((r-32) >> 31));
257                 /*
258                  * If r >= 32, this sets bit 64-r in m1.
259                  * Otherwise, it does nothing.
260                  */
261                 r -= 32;
262                 m1 |= (~r >> 31 & 1) << r;
263 #endif
264         }
265         /*
266          * Done reading input.  Update bit buffer.
267          */
268         bb_ = bb;
269         nbb_ = nbb;
270         *mask = m0;
271 #ifndef INT_64
272         mask[1] = m1;
273 #endif
274         DUMPBITS('\n');
275         return (nc);
276 }
277 
278 /*
279  * Parse a picture header.  We assume that the
280  * start code has already been snarfed.
281  */
282 int P64Dumper::parse_picture_hdr()
283 {
284         u_int tr;
285         GET_BITS(bs_, 5, nbb_, bb_, tr);
286         u_int pt;
287         GET_BITS(bs_, 6, nbb_, bb_, pt);
288         u_int fmt = (pt >> 2) & 1;
289         if (fmt_ != fmt) {
290                 err("unexpected picture type %d/%d", fmt, fmt_);
291                 return (-1);
292         }
293         int v;
294         GET_BITS(bs_, 1, nbb_, bb_, v);
295         printf("pic tr %d pt 0x%02x x%d ", tr, pt, v);
296         while (v != 0) {
297                 GET_BITS(bs_, 9, nbb_, bb_, v);
298                 /*
299                  * FIXME from pvrg code: 0x8c in PSPARE means ntsc.
300                  * this is a hack.  we don't support it.
301                  */
302                 int pspare = v >> 1;
303                 if (pspare == 0x8c && (pt & 0x04) != 0) {
304                         static int first = 1;
305                         if (first) {
306                                 err("pvrg ntsc not supported");
307                                 first = 0;
308                         }
309                 }
310                 v &= 1;
311         }
312         return (0);
313 }
314 
315 inline int P64Dumper::parse_sc()
316 {
317         int v;
318         GET_BITS(bs_, 16, nbb_, bb_, v);
319         DUMPBITS('\n');
320         if (v != 0x0001) {
321                 err("bad start code %04x", v);
322                 ++bad_psc_;
323                 return (-1);
324         }
325         return (0);
326 }
327 
328 /*
329  * Parse a GOB header, which consists of the GOB quantiation
330  * factor (GQUANT) and spare bytes that we ignore.
331  */
332 int P64Dumper::parse_gob_hdr(int ebit)
333 {
334         mba_ = -1;
335         mvdh_ = 0;
336         mvdv_ = 0;
337 
338         /*
339          * Get the next GOB number (or 0 for a picture header).
340          * The invariant at the top of this loop is that the
341          * bit stream is positioned immediately past the last
342          * start code.
343          */
344         int gob;
345         for (;;) {
346                 GET_BITS(bs_, 4, nbb_, bb_, gob);
347                 if (gob != 0)
348                         break;
349                 /*
350                  * should happen only on first iteration
351                  * (if at all).  pictures always start on
352                  * packet boundaries per section 5 of the
353                  * Internet Draft.
354                  */
355                 if (parse_picture_hdr() < 0) {
356                         ++bad_fmt_;
357                         DUMPBITS('\n');
358                         return (-1);
359                 }
360                 /*
361                  * Check to see that the next 16 bits
362                  * are a start code and throw them away.
363                  * But first check that we have the bits.
364                  */
365                 int nbit = ((es_ - bs_) << 4) + nbb_ - ebit;
366                 if (nbit < 20)
367                         return (0);
368 
369                 if (parse_sc() < 0)
370                         return (-1);
371         }
372         gob -= 1;
373         if (fmt_ == IT_QCIF)
374                 /*
375                  * Number QCIF GOBs 0,1,2 instead of 0,2,4.
376                  */
377                 gob >>= 1;
378 
379         int mq;
380         GET_BITS(bs_, 5, nbb_, bb_, mq);
381         qt_ = &quant_[mq << 8];
382 
383         int v;
384         GET_BITS(bs_, 1, nbb_, bb_, v);
385         printf("gob %d q %d x%d ", gob_, mq, v);
386         while (v != 0) {
387                 GET_BITS(bs_, 9, nbb_, bb_, v);
388                 v &= 1;
389         }
390         DUMPBITS('\n');
391 
392         gob_ = gob;
393 
394         return (gob);
395 }
396 
397 /*
398  * Parse a macroblock header.  If there is no mb header because
399  * we hit the next start code, return -1, otherwise 0.
400  */
401 int P64Dumper::parse_mb_hdr(u_int& cbp)
402 {
403         /*
404          * Read the macroblock address (MBA), throwing
405          * away any prefixed stuff bits.
406          */
407         int v;
408         HUFF_DECODE(bs_, ht_mba_, nbb_, bb_, v);
409         if (v <= 0) {
410                 if (v == SYM_STUFFBITS) {
411                         printf("pad ");
412                         DUMPBITS('\n');
413                 }
414                 /*
415                  * (probably) hit a start code; either the
416                  * next GOB or the next picture header.
417                  */
418                 return (v);
419         }
420 
421         /*
422          * MBA is differentially encoded.
423          */
424         mba_ += v;
425         if (mba_ >= MBPERGOB) {
426                 printf("mba? %d ", mba_);
427                 DUMPBITS('\n');
428                 err("mba too big %d", mba_);
429                 return (SYM_ILLEGAL);
430         }
431 
432         u_int omt = mt_;
433         HUFF_DECODE(bs_, ht_mtype_, nbb_, bb_, mt_);
434         printf("mba %d ", mba_);
435         if (mt_ & MT_INTRA)
436                 printf("intra ");
437         if (mt_ & MT_FILTER)
438                 printf("filter ");
439         if (mt_ & MT_MQUANT) {
440                 int mq;
441                 GET_BITS(bs_, 5, nbb_, bb_, mq);
442                 qt_ = &quant_[mq << 8];
443                 printf("q %d ", mq);
444         }
445         if (mt_ & MT_MVD) {
446                 /*
447                  * Read motion vector.
448                  */
449                 int dh;
450                 int dv;
451                 HUFF_DECODE(bs_, ht_mvd_, nbb_, bb_, dh);
452                 HUFF_DECODE(bs_, ht_mvd_, nbb_, bb_, dv);
453                 printf("mv(%d,%d) ", dh, dv);
454                 /*
455                  * Section 4.2.3.4
456                  * The vector is differentially coded unless any of:
457                  *   - the current mba delta isn't 1
458                  *   - the current mba is 1, 12, or 23 (mba mod 11 = 1)
459                  *   - the last block didn't have motion vectors.
460                  *
461                  * This arithmetic is twos-complement restricted
462                  * to 5 bits.  FIXME this code is broken
463                  */
464                 if ((omt & MT_MVD) != 0 && v == 1 &&
465                     mba_ != 0 && mba_ != 11 && mba_ != 22) {
466                         dh += mvdh_;
467                         dv += mvdv_;
468                 }
469                 mvdh_ = (dh << 27) >> 27;
470                 mvdv_ = (dv << 27) >> 27;
471         }
472         /*
473          * Coded block pattern.
474          */
475         if (mt_ & MT_CBP) {
476                 HUFF_DECODE(bs_, ht_cbp_, nbb_, bb_, cbp);
477                 printf("cbp %02x ", cbp);
478                 if (cbp > 63) {
479                         DUMPBITS('\n');
480                         err("cbp invalid %x", cbp);
481                         return (SYM_ILLEGAL);
482                 }
483         } else
484                 cbp = 0x3f;
485 
486         DUMPBITS('\n');
487         return (1);
488 }
489 
490 /*
491  * Handle the next block in the current macroblock.
492  * If tc is non-zero, then coeffcients are present
493  * in the input stream and they are parsed.  Otherwise,
494  * coefficients are not present, but we take action
495  * according to the type macroblock that we have.
496  */
497 void P64Dumper::decode_block(u_int tc, u_int x, u_int y, u_int stride,
498                               u_char* front, u_char* back, int sf, int n)
499 {
500         if (tc != 0)
501                 printf("blk %d ", n);
502         short blk[64];
503 #ifdef INT_64
504         INT_64 mask;
505 #define MASK_VAL        mask
506 #define MASK_REF        &mask
507 #else
508         u_int mask[2];
509 #define MASK_VAL        mask[0], mask[1]
510 #define MASK_REF        mask
511 #endif
512         if (tc != 0)
513                 parse_block(blk, MASK_REF);
514 
515         int off = y * stride + x;
516         u_char* out = front + off;
517 
518         if (mt_ & MT_INTRA) {
519                 if (tc != 0)
520                         rdct(blk, MASK_VAL, out, stride, (u_char*)0);
521                 else {
522                         u_char* in = back + off;
523                         mvblka(in, out, stride);
524                 }
525                 return;
526         }
527         if ((mt_ & MT_MVD) == 0) {
528                 u_char* in = back + off;
529                 if (tc != 0)
530                         rdct(blk, MASK_VAL, out, stride, in);
531                 else
532                         mvblka(in, out, stride);
533                 return;
534         }
535         u_int sx = x + (mvdh_ / sf);
536         u_int sy = y + (mvdv_ / sf);
537         u_char* in = back + sy * stride + sx;
538         if (mt_ & MT_FILTER) {
539                 filter(in, out, stride);
540                 if (tc != 0)
541                         rdct(blk, MASK_VAL, out, stride, out);
542         } else {
543                 if (tc != 0)
544                         rdct(blk, MASK_VAL, out, stride, in);
545                 else
546                         mvblk(in, out, stride);
547         }
548 }
549 
550 /*
551  * Decompress the next macroblock.  Return 0 if the macroblock
552  * was present (with no errors).  Return SYM_STARTCODE (-1),
553  * if there was no macroblock but instead the start of the
554  * next GOB or picture (in which case the start code has
555  * been consumed).  Return SYM_ILLEGAL (-2) if there was an error.
556  */
557 int P64Dumper::decode_mb()
558 {
559         u_int cbp;
560         register int v;
561 
562         if ((v = parse_mb_hdr(cbp)) <= 0)
563                 return (v);
564 
565         /*
566          * Lookup the base coordinate for this MBA.
567          * Convert from a block to a pixel coord.
568          */
569         register u_int x, y;
570         x = coord_[mba_];
571         y = (x & 0xff) << 3;
572         x >>= 8;
573         x <<= 3;
574 
575         /* Update bounding box */
576         if (x < minx_)
577                 minx_ = x;
578         if (x > maxx_)
579                 maxx_ = x;
580         if (y < miny_)
581                 miny_ = y;
582         if (y > maxy_)
583                 maxy_ = y;
584 
585         /*
586          * Decode the six blocks in the MB (4Y:1U:1V).
587          * (This code assumes MT_TCOEFF is 1.)
588          */
589         register u_int tc = mt_ & MT_TCOEFF;
590         register u_int s = width_;
591         decode_block(tc & (cbp >> 5), x, y, s, front_, back_, 1, 1);
592         decode_block(tc & (cbp >> 4), x + 8, y, s, front_, back_, 1, 2);
593         decode_block(tc & (cbp >> 3), x, y + 8, s, front_, back_, 1, 3);
594         decode_block(tc & (cbp >> 2), x + 8, y + 8, s, front_, back_, 1, 4);
595         s >>= 1;
596         int off = size_;
597         decode_block(tc & (cbp >> 1), x >> 1, y >> 1, s,
598                      front_ + off, back_ + off, 2, 5);
599         off += size_ >> 2;
600         decode_block(tc & (cbp >> 0), x >> 1, y >> 1, s,
601                      front_ + off, back_ + off, 2, 6);
602 
603         mbst_[mba_] = MBST_NEW;
604         /*
605          * If a marking table was attached, take note.
606          * This allows us to dither only the blocks that have changed,
607          * rather than the entire image on each frame.
608          */
609         if (marks_) {
610                 /* convert to 8x8 block offset */
611                 off = (x >> 3) + (y >> 3) * (width_ >> 3);
612                 int m = mark_;
613                 marks_[off] = m;
614                 marks_[off + 1] = m;
615                 off += width_ >> 3;
616                 marks_[off] = m;
617                 marks_[off + 1] = m;
618         }
619         return (0);
620 }
621 
622 /*
623  * Decode H.261 stream.  Decoding can begin on either
624  * a GOB or macroblock header.  All the macroblocks of
625  * a given frame can be decoded in any order, but chunks
626  * cannot be reordered across frame boundaries.  Since data
627  * can be decoded in any order, this entry point can't tell
628  * when a frame is fully decoded (actually, we could count
629  * macroblocks but if there is loss, we would not know when
630  * to sync).  Instead, the callee should sync the decoder
631  * by calling the sync() method after the entire frame
632  * has been decoded (modulo loss).
633  *
634  * This routine should not be called with more than
635  * one frame present since there is no callback mechanism
636  * for renderering frames (i.e., don't call this routine
637  * with a buffer that has a picture header that's not
638  * at the front).
639  */
640 int P64Dumper::decode(const u_char* bp, int cc, int sbit, int ebit,
641                       int mba, int gob, int mq, int mvdh, int mvdv)
642 {
643         ps_ = (u_short*)bp;
644         /*
645          * If cc is even, ignore 8 extra bits in last short.
646          */
647         int odd = cc & 1;
648         ebit += (odd ^ 1) << 3;
649         pebit_ = ebit;
650         cc -= odd;
651         es_ = (u_short*)(bp + cc);
652 
653         /*
654          * If input buffer not aligned, prime bit-buffer
655          * with 8 bits; otherwise, prime it with a 16.
656          */
657         if ((int)bp & 1) {
658                 bs_ = (u_short*)(bp + 1);
659                 bb_ = *bp;
660                 nbb_ = 8 - sbit;
661         } else {
662                 bs_ = (u_short*)bp;
663                 HUFFRQ(bs_, bb_);
664                 nbb_ = 16 - sbit;
665         }
666         dbs_ = bs_;
667         dnbb_ = nbb_;
668         dbb_ = bb_;
669 
670         mba_ = mba;
671         qt_ = &quant_[mq << 8];
672         mvdh_ = mvdh;
673         mvdv_ = mvdv;
674         /*FIXME don't rely on this*/
675         if (gob != 0) {
676                 gob -= 1;
677                 if (fmt_ == IT_QCIF)
678                         gob >>= 1;
679         }
680 
681         while (bs_ < es_ || (bs_ == es_ && nbb_ > ebit)) {
682                 mbst_ = &mb_state_[gob << 6];
683                 coord_ = &base_[gob << 6];
684 
685                 int v = decode_mb();
686                 if (v == 0)
687                         continue;
688 
689                 if (v != SYM_STARTCODE) {
690                         ++bad_bits_;
691                         return (0);
692                 }
693                 gob = parse_gob_hdr(ebit);
694                 if (gob < 0) {
695                         /*FIXME*/
696                         ++bad_bits_;
697                         return (0);
698                 }
699         }
700         fflush(stdout);
701         return (1);
702 }
703 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.