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

Open Mash Cross Reference
mash/codec/decoder-h263-lim.cc

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

  1 /*
  2  * decoder-h263.cc --
  3  *
  4  *      Source code for H.263 video decoder object.
  5  *
  6  * Copyright (c) 2002-2002 The Regents of the University of California.
  7  * All rights reserved.
  8  *
  9  * Redistribution and use in source and binary forms, with or without
 10  * modification, are permitted provided that the following conditions are met:
 11  *
 12  * A. Redistributions of source code must retain the above copyright notice,
 13  *    this list of conditions and the following disclaimer.
 14  * B. Redistributions in binary form must reproduce the above copyright notice,
 15  *    this list of conditions and the following disclaimer in the documentation
 16  *    and/or other materials provided with the distribution.
 17  * C. Neither the names of the copyright holders nor the names of its
 18  *    contributors may be used to endorse or promote products derived from this
 19  *    software without specific prior written permission.
 20  *
 21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 22  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 31  * POSSIBILITY OF SUCH DAMAGE.
 32  */
 33 
 34 
 35 #include <stdio.h>
 36 #include <stdlib.h>
 37 #include <string.h>
 38 #include "inet.h"
 39 #include "rtp.h"
 40 #include "decoder.h"
 41 #include "renderer.h"
 42 #include "pktbuf.h"
 43 #include "postdct.h"
 44 
 45 #include "decoder-h263.h"
 46 
 47 
 48 static class H263DecoderClass : public TclClass {
 49                 public:
 50         H263DecoderClass() : TclClass("Module/VideoDecoder/H263") {}
 51         TclObject* create(int /* argc */, const char*const* /* argv */) {
 52                 return (new H263Decoder);
 53         };
 54 } dm_h263;
 55 
 56 
 57 
 58 #define DUMP_INFO 1
 59 
 60 
 61 #define STAT_BAD_PSC    0
 62 #define STAT_BAD_GOB    1
 63 #define STAT_BAD_SYNTAX 2
 64 #define STAT_BAD_FMT    3
 65 #define STAT_FMT_CHANGE 4       /* # times fmt changed */
 66 #define STAT_BAD_HEADER 5
 67 
 68 
 69 H263Decoder::H263Decoder() : Decoder(4), codec_(0), last_seqno_(0)
 70 {
 71         stat_[STAT_BAD_PSC].name = "H263-Bad-PSC";
 72         stat_[STAT_BAD_GOB].name = "H263-Bad-GOB";
 73         stat_[STAT_BAD_SYNTAX].name = "H263-Bad-Syntax";
 74         stat_[STAT_BAD_FMT].name = "H263-Bad-fmt";
 75         stat_[STAT_FMT_CHANGE].name = "H263-Fmt-change";
 76         stat_[STAT_BAD_HEADER].name = "H263-Bad-Header";
 77         nstat_ = 6;
 78 
 79         csss_ = 420;
 80         /*
 81          * Assume CIF.  Picture header will trigger a resize if
 82          * we encounter QCIF instead.
 83          */
 84         inw_ = 352;
 85         inh_ = 288;
 86 
 87         /*FIXME*/
 88         resize(inw_, inh_);
 89 }
 90 
 91 H263Decoder::~H263Decoder()
 92 {
 93         delete codec_;
 94 }
 95 
 96 void H263Decoder::info(char* wrk) const
 97 {
 98         if (codec_ == 0)
 99                 *wrk = 0;
100         else
101                 sprintf(wrk, "[q=%d]", codec_->gobquant());
102 }
103 
104 void H263Decoder::stats(char* wrk)
105 {
106         /* pull stats out of vic indepdendent P64Decoder */
107         setstat(STAT_BAD_PSC, codec_->bad_psc());
108         setstat(STAT_BAD_GOB, codec_->bad_GOBno());
109         setstat(STAT_BAD_SYNTAX, codec_->bad_bits());
110         setstat(STAT_BAD_FMT, codec_->bad_fmt());
111         Decoder::stats(wrk);
112 }
113 
114 int H263Decoder::colorhist(u_int* hist) const
115 {
116         const u_char* frm = codec_->frame();
117         int w = inw_;
118         int h = inh_;
119         int s = w * h;
120         colorhist_420_556(hist, frm, frm + s, frm + s + (s >> 2), w, h);
121         return (1);
122 }
123 
124 
125 #ifdef CR_STATS
126 u_char shadow[640*480/64];
127 
128 void dumpShadow(u_int32_t ts, u_char* p, int nblk)
129 {
130         ts &= 0x7fffffff;
131         static u_int32_t lastTS = 0;
132         if (ts != lastTS) {
133                 printf("ts %u\n", ts);
134                 lastTS = ts;
135         }
136         int left = -1;
137         for (int i = 0; i < nblk; ++i) {
138                 if (shadow[i] != p[i]) {
139                         if (left < 0) {
140                                 left = i;
141                         }
142                 } else {
143                         if (left > 0)
144                                 printf("b %d %d\n", left, i - 1);
145                         left = -1;
146                 }
147         }
148         if (left > 0)
149                 printf("b %d %d\n", left, i - 1);
150 }
151 #endif
152 
153 void H263Decoder::recv(pktbuf* pb)
154 {
155     rtphdr* rh = (rtphdr*)pb->dp;           /* RTP header */
156     u_int16_t seqno = ntohs(rh->rh_seqno);  /* RTP sequence number */
157     u_int8_t* vh = (u_int8_t*)(rh + 1);     /* video header */
158     int vhsize;                             /* video header size */
159 
160     if (codec_ == 0) {
161         codec_ = new H263BitstreamDecoder();
162         codec_->marks(rvts_);
163     }
164 #ifdef CR_STATS
165         memcpy(shadow, rvts_, nblk_);
166 #endif
167 
168     int fflag = vh[0] >> 7;
169     int pflag = (vh[0] >> 6) & 0x01;
170     int sbit = (vh[0] >> 3) & 0x07;
171     int ebit = vh[0] & 0x07;
172     int src = vh[1] >> 5;
173     int iflag, uflag, sflag, aflag;
174     int dbq, trb, tr;
175     int quant, gob, mba, mvdh1, mvdv1, mvdh2, mvdv2;
176 
177     /*
178      * Mode A packet.
179      */
180     if (!fflag) {
181         vhsize = 4;
182 
183         iflag = (vh[1] >> 4) & 0x01;
184         uflag = (vh[1] >> 3) & 0x01;
185         sflag = (vh[1] >> 2) & 0x01;
186         aflag = (vh[1] >> 1) & 0x01;
187         dbq = (vh[2] >> 3) & 0x03;
188         trb = vh[2] & 0x07;
189         tr = vh[3];
190 
191         quant = 0;
192         mba = 0;
193 
194         /*
195          * I-picture or P-picture.
196          */
197         if (!pflag) {
198 #if DUMP_INFO
199             printf("mode A packet received with I-picture or P-picture\n");
200 #endif
201 
202         /*
203          * PB-frame.
204          */
205         } else {
206             /*
207              * The optional PB-frame mode is not supported.
208              */
209 #if DUMP_INFO
210             printf("mode A packet received with PB-frame\n");
211 #endif
212         }
213 
214         /*
215          * Mode A packets don't contain a GOB number so we tell the codec
216          * whether or not the previous packet was received.
217          */
218         if (seqno == last_seqno_ + 1) {
219             /*
220              * The previous packet was received.
221              */
222             gob = SEQUENTIAL_PACKET;
223         } else {
224             /*
225              * The previous packet was not received.
226              */
227             gob = NONSEQUENTIAL_PACKET;
228 #if DUMP_INFO
229             printf("previous packet was not received\n");
230             printf("last sequence number = %d, current sequence number = %d\n",
231                    last_seqno_, seqno);
232 #endif
233         }
234 
235     /*
236      * Mode B packet.
237      */
238     } else if (!pflag) {
239         vhsize = 8;
240 
241         u_int32_t v = ntohl(*(u_int32_t*)vh);
242         quant = (v >> 16) & 0x1F;
243         gob = (v >> 11) & 0x1F;
244         mba = (v >> 2) & 0x1FF;
245         iflag = (vh[4] >> 7) & 0x01;
246         uflag = (vh[4] >> 6) & 0x01;
247         sflag = (vh[4] >> 5) & 0x01;
248         aflag = (vh[4] >> 4) & 0x01;
249         v = ntohl(*(u_int32_t*)&vh[4]);
250         mvdh1 = (v >> 21) & 0x7F;
251         mvdv1 = (v >> 14) & 0x7F;
252         mvdh2 = (v >> 7) & 0x7F;
253         mvdv2 = v & 0x7F;
254 
255 #if DUMP_INFO
256         printf("mode B packet received\n");
257 #endif
258 
259         /*
260          * Mode B packets from UCL vic always contain the same GOB number.  We
261          * work around this bug by treating these packets like mode A packets.
262          */
263         if (gob == codec_->ngob() - 1) {
264             if (seqno == last_seqno_ + 1) {
265                 /*
266                  * The previous packet was received.
267                  */
268                 gob = SEQUENTIAL_PACKET;
269             } else {
270                 /*
271                  * The previous packet was not received.
272                  */
273                 gob = NONSEQUENTIAL_PACKET;
274 #if DUMP_INFO
275                 printf("previous packet was not received\n");
276                 printf("last sequence number = %d,"
277                        " current sequence number = %d\n", last_seqno_, seqno);
278 #endif
279             }
280         }
281 
282     /*
283      * Mode C packet.
284      */
285     } else {
286         vhsize = 12;
287 
288         u_int32_t v = ntohl(*(u_int32_t*)vh);
289         quant = (v >> 16) & 0x1F;
290         gob = (v >> 11) & 0x1F;
291         mba = (v >> 2) & 0x1FF;
292         iflag = (vh[4] >> 7) & 0x01;
293         uflag = (vh[4] >> 6) & 0x01;
294         sflag = (vh[4] >> 5) & 0x01;
295         aflag = (vh[4] >> 4) & 0x01;
296         v = ntohl(*(u_int32_t*)&vh[4]);
297         mvdh1 = (v >> 21) & 0x7F;
298         mvdv1 = (v >> 14) & 0x7F;
299         mvdh2 = (v >> 7) & 0x7F;
300         mvdv2 = v & 0x7F;
301         dbq = (vh[10] >> 3) & 0x03;
302         trb = vh[10] & 0x07;
303         tr = vh[11];
304 
305         /*
306          * The optional PB-frame mode is not supported.
307          */
308 #if DUMP_INFO
309         printf("mode C packet received\n");
310 #endif
311     }
312 
313     last_seqno_ = seqno;
314 
315     if (gob > MAX_NUM_GOBS) {
316 printf("bad gob value received\n"); // FIXME
317         count(STAT_BAD_HEADER);
318         pb->release();
319         return;
320     }
321 
322     int cc = pb->len - (sizeof(*rh) + vhsize);
323     codec_->mark(now_);
324     (void)codec_->decode(vh + vhsize, cc, sbit, ebit,
325                          mba, gob, quant, mvdh1, mvdv1, mvdh2, mvdv2);
326 #ifdef CR_STATS
327         dumpShadow(ntohl(rh->rh_ts), rvts_, nblk_);
328 #endif
329 #if 0
330         /*
331          * If the stream changes format, issue a resize.
332          */
333         if (codec_->width() != inw_) {
334                 resize(codec_->width(), codec_->height());
335                 codec_->marks(rvts_);
336                 count(STAT_FMT_CHANGE);
337         }
338 
339         /*FIXME*/
340         if (ntohs(rh->rh_flags) & RTP_M) {
341 #if DUMP_INFO
342             printf("packet is marked as the end of frame\n");
343 #endif
344  //printf ("now_ = %2x, timestamp = %d\n", now_, ntohl(rh->rh_ts)); // XXX
345 #endif
346                 codec_->sync();
347                 ndblk_ = codec_->ndblk();
348                 render_frame(codec_->frame(), CODEC_H261, quant);
349                 codec_->resetndblk();
350 #if 0
351     }
352 #endif
353         pb->release();
354 }
355 
356 void H263Decoder::redraw()
357 {
358         if (codec_ != 0)
359                 Decoder::redraw(codec_->frame());
360 }
361 

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