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

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

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

  1 /*
  2  * decoder-h261.cc --
  3  *
  4  *   Source code for H.261 Video Decoder object
  5  *
  6  * Copyright (c) 1993-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 "rtp/inet.h"
 39 #include "rtp/rtp.h"
 40 #include "codec/decoder.h"
 41 #include "render/renderer.h"
 42 #include "codec/p64/p64.h"
 43 #include "net/pktbuf.h"
 44 #include "codec/postdct.h"
 45 
 46 #include "codec/decoder-h261.h"
 47 
 48 
 49 static class H261DecoderClass : public TclClass {
 50                 public:
 51         H261DecoderClass() : TclClass("Module/VideoDecoder/H261") {}
 52         TclObject* create(int /* argc */, const char*const* /* argv */) {
 53                 return (new H261Decoder);
 54         };
 55 } dm_h261;
 56 
 57 
 58 
 59 #define STAT_BAD_PSC    0
 60 #define STAT_BAD_GOB    1
 61 #define STAT_BAD_SYNTAX 2
 62 #define STAT_BAD_FMT    3
 63 #define STAT_FMT_CHANGE 4       /* # times fmt changed */
 64 #define STAT_BAD_HEADER 5
 65 
 66 
 67 H261Decoder::H261Decoder() : Decoder(4), codec_(0), h261_rtp_bug_(0)
 68 {
 69         stat_[STAT_BAD_PSC].name = "H261-Bad-PSC";
 70         stat_[STAT_BAD_GOB].name = "H261-Bad-GOB";
 71         stat_[STAT_BAD_SYNTAX].name = "H261-Bad-Syntax";
 72         stat_[STAT_BAD_FMT].name = "H261-Bad-fmt";
 73         stat_[STAT_FMT_CHANGE].name = "H261-Fmt-change";
 74         stat_[STAT_BAD_HEADER].name = "H261-Bad-Header";
 75         nstat_ = 6;
 76 
 77         csss_ = 420;
 78         /*
 79          * Assume CIF.  Picture header will trigger a resize if
 80          * we encounter QCIF instead.
 81          */
 82         inw_ = 352;
 83         inh_ = 288;
 84 
 85         /*FIXME*/
 86         resize(inw_, inh_);
 87 }
 88 
 89 H261Decoder::~H261Decoder()
 90 {
 91         delete codec_;
 92 }
 93 
 94 void H261Decoder::info(char* wrk) const
 95 {
 96         if (codec_ == 0)
 97                 *wrk = 0;
 98         else
 99                 sprintf(wrk, "[q=%d]", codec_->gobquant());
100 }
101 
102 void H261Decoder::stats(char* wrk)
103 {
104         /* pull stats out of vic indepdendent P64Decoder */
105         setstat(STAT_BAD_PSC, codec_->bad_psc());
106         setstat(STAT_BAD_GOB, codec_->bad_GOBno());
107         setstat(STAT_BAD_SYNTAX, codec_->bad_bits());
108         setstat(STAT_BAD_FMT, codec_->bad_fmt());
109         Decoder::stats(wrk);
110 }
111 
112 int H261Decoder::colorhist(u_int* hist) const
113 {
114         const u_char* frm = codec_->frame();
115         int w = inw_;
116         int h = inh_;
117         int s = w * h;
118         colorhist_420_556(hist, frm, frm + s, frm + s + (s >> 2), w, h);
119         return (1);
120 }
121 
122 
123 #ifdef CR_STATS
124 u_char shadow[640*480/64];
125 
126 void dumpShadow(u_int32_t ts, u_char* p, int nblk)
127 {
128         ts &= 0x7fffffff;
129         static u_int32_t lastTS = 0;
130         if (ts != lastTS) {
131                 printf("ts %u\n", ts);
132                 lastTS = ts;
133         }
134         int left = -1;
135         for (int i = 0; i < nblk; ++i) {
136                 if (shadow[i] != p[i]) {
137                         if (left < 0) {
138                                 left = i;
139                         }
140                 } else {
141                         if (left > 0)
142                                 printf("b %d %d\n", left, i - 1);
143                         left = -1;
144                 }
145         }
146         if (left > 0)
147                 printf("b %d %d\n", left, i - 1);
148 }
149 #endif
150 
151 void H261Decoder::recv(pktbuf* pb)
152 {
153         rtphdr* rh = (rtphdr*)pb->dp;
154         u_int8_t* vh = (u_int8_t*)(rh + 1);
155         if (codec_ == 0) {
156                 if ((vh[0] & 2) != 0)
157                         codec_ = new IntraP64Decoder();
158                 else
159                         codec_ = new FullP64Decoder();
160                 codec_->marks(rvts_);
161         }
162 #ifdef CR_STATS
163         memcpy(shadow, rvts_, nblk_);
164 #endif
165         u_int v = ntohl(*(u_int32_t*)vh);
166         int sbit = v >> 29;
167         int ebit = (v >> 26) & 7;
168         int quant = (v >> 10) & 0x1f;
169         int mvdh = (v >> 5) & 0x1f;
170         int mvdv = v & 0x1f;
171         int mba, gob;
172         /*
173          * vic-2.7 swapped the GOB and MBA fields in the RTP packet header
174          * with respect to the spec.  To maintain backward compat, whenever
175          * we see an out of range gob, we change our assumption about the
176          * stream and continue.
177          */
178         if (!h261_rtp_bug_) {
179                 mba = (v >> 15) & 0x1f;
180                 gob = (v >> 20) & 0xf;
181                 if (gob > 12) {
182                         h261_rtp_bug_ = 1;
183                         mba = (v >> 19) & 0x1f;
184                         gob = (v >> 15) & 0xf;
185                 }
186         } else {
187                 mba = (v >> 19) & 0x1f;
188                 gob = (v >> 15) & 0xf;
189                 if (gob > 12) {
190                         h261_rtp_bug_ = 0;
191                         mba = (v >> 15) & 0x1f;
192                         gob = (v >> 20) & 0xf;
193                 }
194         }
195 
196         if (gob > 12) {
197                 count(STAT_BAD_HEADER);
198                 pb->release();
199                 return;
200         }
201         int cc = pb->len - (sizeof(*rh) + 4);
202         codec_->mark(now_);
203         (void)codec_->decode(vh + 4, cc, sbit, ebit,
204                              mba, gob, quant, mvdh, mvdv);
205 #ifdef CR_STATS
206         dumpShadow(ntohl(rh->rh_ts), rvts_, nblk_);
207 #endif
208         /*
209          * If the stream changes format, issue a resize.
210          */
211         if (codec_->width() != inw_) {
212                 resize(codec_->width(), codec_->height());
213                 codec_->marks(rvts_);
214                 count(STAT_FMT_CHANGE);
215         }
216 
217         /*FIXME*/
218         if (ntohs(rh->rh_flags) & RTP_M) {
219  //printf ("now_ = %2x, timestamp = %d\n", now_, ntohl(rh->rh_ts)); // XXX
220                 codec_->sync();
221                 ndblk_ = codec_->ndblk();
222                 render_frame(codec_->frame(), CODEC_H261, quant);
223                 codec_->resetndblk();
224         }
225         pb->release();
226 }
227 
228 void H261Decoder::redraw()
229 {
230         if (codec_ != 0)
231                 Decoder::redraw(codec_->frame());
232 }
233 

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