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

Open Mash Cross Reference
mash/codec/decoder-cellb.cc

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

  1 /*
  2  * decoder-cellb.cc --
  3  *
  4  *      CellB decoder
  5  */
  6 
  7 /* This code was originally derived from a cellb reference decoder from
  8  * Sun Microsystems with the following copyright:
  9  *
 10  * Copyright (c) Sun Microsystems, Inc.  1992, 1993. All rights reserved.
 11  *
 12  * License is granted to copy, to use, and to make and to use derivative
 13  * works for research and evaluation purposes, provided that Sun Microsystems is
 14  * acknowledged in all documentation pertaining to any such copy or derivative
 15  * work. Sun Microsystems grants no other licenses expressed or implied. The
 16  * Sun Microsystems  trade name should not be used in any advertising without
 17  * its written permission.
 18  *
 19  * SUN MICROSYSTEMS MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF
 20  * THIS SOFTWARE FOR ANY PARTICULAR PURPOSE.  The software is provided "as is"
 21  * without express or implied warranty of any kind.
 22  *
 23  * These notices must be retained in any copies of any part of this software.
 24  */
 25 
 26 static const char rcsid[] =
 27     "@(#) $Header: /usr/mash/src/repository/mash/mash-1/codec/decoder-cellb.cc,v 1.11 2003/11/19 19:20:17 aswan Exp $";
 28 
 29 #include <stdio.h>
 30 #include <string.h>
 31 #include "rtp/inet.h"
 32 #include "rtp/rtp.h"
 33 #include "codec/decoder.h"
 34 #include "misc/bsd-endian.h"
 35 #include "net/pktbuf.h"
 36 
 37 class CellbDecoder : public PlaneDecoder {
 38 public:
 39         CellbDecoder();
 40 protected:
 41         virtual void recv(pktbuf*);
 42         void decode(const u_char*, int cc, int x, int y, int w, int h);
 43 };
 44 
 45 static class CellbDecoderClass : public TclClass {
 46 public:
 47         CellbDecoderClass() : TclClass("Module/VideoDecoder/CellB") {}
 48         TclObject* create(int /* argc */, const char*const* /* argv */) {
 49                 return (new CellbDecoder);
 50         }
 51 } dm_cellb;
 52 
 53 #define STAT_BAD_GEOM 0
 54 #define STAT_BAD_COORD 1
 55 
 56 CellbDecoder::CellbDecoder() : PlaneDecoder(sizeof(cellbhdr))
 57 {
 58         stat_[STAT_BAD_GEOM].name = "Cellb-Bad-Geom";
 59         stat_[STAT_BAD_COORD].name = "Cellb-Bad-Coord";
 60         nstat_ = 2;
 61 
 62         color_ = 1;
 63         inw_ = 0;
 64         inh_ = 0;
 65         csss_ = 422;
 66 }
 67 
 68 /*
 69  * Inverse VQ tables.
 70  */
 71 extern "C" u_short cellb_yytable[256], cellb_uvtable[256];
 72 
 73 void CellbDecoder::decode(const u_char* p, int cc, int cellx, int celly,
 74                           int width, int height)
 75 {
 76         /* Convert width to count in cells */
 77         width >>= 2;
 78         height >>= 2;
 79 
 80         while (cc >= 4) {
 81                 int mask = *p;
 82                 if (mask & 0x80) {
 83                         cellx += mask - 127;
 84                         while (cellx >= width) {
 85                                 cellx -= width;
 86                                 ++celly;
 87                         }
 88                         ++p;
 89                         --cc;
 90                 } else {
 91                         mask <<= 8;
 92                         mask |= p[1];
 93 
 94                         /*FIXME yytable is backward so flip mask bits*/
 95                         mask ^= 0xffff;
 96                         int yy = cellb_yytable[p[3]];
 97 
 98                         if (celly >= height) {
 99                                 /*FIXME*/
100                                 fprintf(stderr, "vic: bad cellb packet\n");
101                                 return;
102                         }
103                         int k = 4 * (celly * 4 * width + cellx);
104                         u_int* yp = (u_int*)&frm_[k];
105 
106 #if BYTE_ORDER == LITTLE_ENDIAN
107 #define MSET(y, yy, mask, pos) \
108                         { \
109                                 int t = (((mask) >> (pos)) & 1) << 3; \
110                                 y >>= 8; \
111                                 y |= ((yy) >> t) << 24; \
112                         }
113 #else
114 #define MSET(y, yy, mask, pos) \
115                         { \
116                                 int t = (((mask) >> (pos)) & 1) << 3; \
117                                 y <<= 8; \
118                                 y |= ((yy) >> t) & 0xff; \
119                         }
120 #endif
121                         /* First bit of mask is clear. */
122 #if BYTE_ORDER == LITTLE_ENDIAN
123                         u_int y = (yy >> 8) << 24;
124 #else
125                         u_int y = yy >> 8;
126 #endif
127                         MSET(y, yy, mask, 14);
128                         MSET(y, yy, mask, 13);
129                         MSET(y, yy, mask, 12);
130                         *yp = y;
131                         yp += width;
132 
133                         MSET(y, yy, mask, 11);
134                         MSET(y, yy, mask, 10);
135                         MSET(y, yy, mask, 9);
136                         MSET(y, yy, mask, 8);
137                         *yp = y;
138                         yp += width;
139 
140                         MSET(y, yy, mask, 7);
141                         MSET(y, yy, mask, 6);
142                         MSET(y, yy, mask, 5);
143                         MSET(y, yy, mask, 4);
144                         *yp = y;
145                         yp += width;
146 
147                         MSET(y, yy, mask, 3);
148                         MSET(y, yy, mask, 2);
149                         MSET(y, yy, mask, 1);
150                         MSET(y, yy, mask, 0);
151                         *yp = y;
152 #undef MSET
153                         int s = (width << 2) * (height << 2);/*FIXME*/
154                         u_char* up = frm_ + s + k / 2;
155                         u_char* vp = up + (s >> 1);
156 
157                         k = p[2];
158                         int uv = cellb_uvtable[k];
159                         int t = uv >> 8;
160                         t |= t << 8;
161                         *(u_short*)up = t; up += width << 1;
162                         *(u_short*)up = t; up += width << 1;
163                         *(u_short*)up = t; up += width << 1;
164                         *(u_short*)up = t;
165                         t = uv & 0xff;
166                         t |= t << 8;
167                         *(u_short*)vp = t; vp += width << 1;
168                         *(u_short*)vp = t; vp += width << 1;
169                         *(u_short*)vp = t; vp += width << 1;
170                         *(u_short*)vp = t;
171 
172                         /* mark block as changed */
173                         /*FIXME should maintain offset using loop */
174                         int o = (cellx >> 1) + (celly >> 1) * (width >> 1);
175                         rvts_[o] = now_;
176 
177                         if (++cellx >= width) {
178                                 cellx -= width;
179                                 ++celly;
180                         }
181                         p += 4;
182                         cc -= 4;
183                 }
184                 ndblk_++;
185         }
186 }
187 
188 void CellbDecoder::recv(pktbuf* pb)
189 {
190         rtphdr* rh = (rtphdr*)pb->dp;
191         cellbhdr* ph = (cellbhdr*)(rh + 1);
192         int w = ntohs(ph->width) & 0x7fff;
193         int h = ntohs(ph->height);
194         if (w != inw_ || h != inh_) {
195                 if ((unsigned)w > 1000 || (unsigned)h > 1000) {
196                         /*FIXME*/
197                         w = 320;
198                         h = 240;
199                         count(STAT_BAD_GEOM);
200                 }
201                 resize(w, h);
202         }
203         int cc = pb->len - (sizeof(*rh) + sizeof(*ph));
204         decode((u_char*)(ph + 1), cc, ntohs(ph->x), ntohs(ph->y), w, h);
205         if (ntohs(rh->rh_flags) & RTP_M) {
206                 render_frame(frm_);
207                 resetndblk();
208         }
209         pb->release();
210 }
211 

~ [ 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.