www.pudn.com > h261_codec.rar > h261.c
Media Tools Repository DEPARTMENT OF COMPUTER SCIENCE Networked Multimedia LoginSettingsHelp/GuideAbout Trac Search: WikiTimelineRoadmapBrowse SourceView TicketsNew TicketSearch Revision Log root/vic/branches/mpeg4/codec/decoder-h261.cpp View revision: Revision 957 (checked in by piers, 7 years ago) ALtered for Layered support using new packet buffer from MASH. So encoders call the tx_->send(pb) method using these new packet buffers. Property svn:eol-style set to native Property svn:keywords set to Author Date Id Revision Line 1 /*- 2 * Copyright (c) 1993-1994 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and the Network Research Group at 17 * Lawrence Berkeley Laboratory. 18 * 4. Neither the name of the University nor of the Laboratory may be used 19 * to endorse or promote products derived from this software without 20 * specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 static const char rcsid[] = 35 "@(#) $Header$ (LBL)"; 36 37 #include38 #include 39 #include 40 #include "inet.h" 41 #include "rtp.h" 42 #include "decoder.h" 43 #include "renderer.h" 44 #include "p64/p64.h" 45 46 class H261Decoder : public Decoder { 47 public: 48 H261Decoder(); 49 virtual ~H261Decoder(); 50 virtual void info(char* wrk) const; 51 virtual void recv(pktbuf*); 52 int colorhist(u_int* hist) const; 53 virtual void stats(char* wrk); 54 protected: 55 void decode(const u_char* vh, const u_char* bp, int cc); 56 virtual void redraw(); 57 P64Decoder* codec_; 58 int h261_rtp_bug_; 59 }; 60 61 static class H261DecoderMatcher : public Matcher { 62 public: 63 H261DecoderMatcher() : Matcher("decoder") {} 64 TclObject* match(const char* id) { 65 if (strcasecmp(id, "h.261") == 0 || 66 strcasecmp(id, "h261") == 0) 67 return (new H261Decoder()); 68 return (0); 69 } 70 } dm_h261; 71 72 #define STAT_BAD_PSC 0 73 #define STAT_BAD_GOB 1 74 #define STAT_BAD_SYNTAX 2 75 #define STAT_BAD_FMT 3 76 #define STAT_FMT_CHANGE 4 /* # times fmt changed */ 77 #define STAT_BAD_HEADER 5 78 79 80 H261Decoder::H261Decoder() : Decoder(4), codec_(0), h261_rtp_bug_(0) 81 { 82 stat_[STAT_BAD_PSC].name = "H261-Bad-PSC"; 83 stat_[STAT_BAD_GOB].name = "H261-Bad-GOB"; 84 stat_[STAT_BAD_SYNTAX].name = "H261-Bad-Syntax"; 85 stat_[STAT_BAD_FMT].name = "H261-Bad-fmt"; 86 stat_[STAT_FMT_CHANGE].name = "H261-Fmt-change"; 87 stat_[STAT_BAD_HEADER].name = "H261-Bad-Header"; 88 nstat_ = 6; 89 90 decimation_ = 411; 91 /* 92 * Assume CIF. Picture header will trigger a resize if 93 * we encounter QCIF instead. 94 */ 95 inw_ = 352; 96 inh_ = 288; 97 98 /*XXX*/ 99 resize(inw_, inh_); 100 } 101 102 H261Decoder::~H261Decoder() 103 { 104 delete codec_; 105 } 106 107 void H261Decoder::info(char* wrk) const 108 { 109 if (codec_ == 0) 110 *wrk = 0; 111 else 112 sprintf(wrk, "[q=%d]", codec_->gobquant()); 113 } 114 115 void H261Decoder::stats(char* wrk) 116 { 117 /* pull stats out of vic indepdendent P64Decoder */ 118 setstat(STAT_BAD_PSC, codec_->bad_psc()); 119 setstat(STAT_BAD_GOB, codec_->bad_GOBno()); 120 setstat(STAT_BAD_SYNTAX, codec_->bad_bits()); 121 setstat(STAT_BAD_FMT, codec_->bad_fmt()); 122 Decoder::stats(wrk); 123 } 124 125 int H261Decoder::colorhist(u_int* hist) const 126 { 127 const u_char* frm = codec_->frame(); 128 int w = inw_; 129 int h = inh_; 130 int s = w * h; 131 colorhist_411_556(hist, frm, frm + s, frm + s + (s >> 2), w, h); 132 return (1); 133 } 134 135 136 #ifdef CR_STATS 137 u_char shadow[640*480/64]; 138 139 void dumpShadow(u_int32_t ts, u_char* p, int nblk) 140 { 141 ts &= 0x7fffffff; 142 static u_int32_t lastTS = 0; 143 if (ts != lastTS) { 144 printf("ts %u\n", ts); 145 lastTS = ts; 146 } 147 int left = -1; 148 for (int i = 0; i < nblk; ++i) { 149 if (shadow[i] != p[i]) { 150 if (left < 0) { 151 left = i; 152 } 153 } else { 154 if (left > 0) 155 printf("b %d %d\n", left, i - 1); 156 left = -1; 157 } 158 } 159 if (left > 0) 160 printf("b %d %d\n", left, i - 1); 161 } 162 #endif 163 164 void H261Decoder::recv(pktbuf* pb) 165 { 166 rtphdr* rh = (rtphdr*)pb->dp; 167 u_int8_t* vh = (u_int8_t*)(rh + 1); 168 if (codec_ == 0) { 169 if ((vh[0] & 2) != 0) 170 codec_ = new IntraP64Decoder(); 171 else 172 codec_ = new FullP64Decoder(); 173 codec_->marks(rvts_); 174 } 175 #ifdef CR_STATS 176 memcpy(shadow, rvts_, nblk_); 177 #endif 178 /*XXX*/ 179 u_int v = ntohl(*(u_int32_t*)vh); 180 int sbit = v >> 29; 181 int ebit = (v >> 26) & 7; 182 int quant = (v >> 10) & 0x1f; 183 int mvdh = (v >> 5) & 0x1f; 184 int mvdv = v & 0x1f; 185 int mba, gob; 186 /* 187 * vic-2.7 swapped the GOB and MBA fields in the RTP packet header 188 * with respect to the spec. To maintain backward compat, whenever 189 * we see an out of range gob, we change our assumption about the 190 * stream and continue. 191 */ 192 if (!h261_rtp_bug_) { 193 mba = (v >> 15) & 0x1f; 194 gob = (v >> 20) & 0xf; 195 if (gob > 12) { 196 h261_rtp_bug_ = 1; 197 mba = (v >> 19) & 0x1f; 198 gob = (v >> 15) & 0xf; 199 } 200 } else { 201 mba = (v >> 19) & 0x1f; 202 gob = (v >> 15) & 0xf; 203 if (gob > 12) { 204 h261_rtp_bug_ = 0; 205 mba = (v >> 15) & 0x1f; 206 gob = (v >> 20) & 0xf; 207 } 208 } 209 210 if (gob > 12) { 211 count(STAT_BAD_HEADER); 212 pb->release(); 213 return; 214 } 215 int cc = pb->len - (sizeof(*rh) + 4); 216 codec_->mark(now_); 217 (void)codec_->decode(vh + 4, cc, sbit, ebit, 218 mba, gob, quant, mvdh, mvdv); 219 #ifdef CR_STATS 220 dumpShadow(ntohl(rh->rh_ts), rvts_, nblk_); 221 #endif 222 /* 223 * If the stream changes format, issue a resize. 224 */ 225 if (codec_->width() != inw_) { 226 resize(codec_->width(), codec_->height()); 227 codec_->marks(rvts_); 228 count(STAT_FMT_CHANGE); 229 } 230 231 /*XXX*/ 232 if (ntohs(rh->rh_flags) & RTP_M) { 233 codec_->sync(); 234 ndblk_ = codec_->ndblk(); 235 render_frame(codec_->frame()); 236 codec_->resetndblk(); 237 } 238 pb->release(); 239 } 240 241 void H261Decoder::redraw() 242 { 243 if (codec_ != 0) 244 Decoder::redraw(codec_->frame()); 245 } Note: See TracBrowser for help on using the browser. Download in other formats: Plain TextOriginal Format Powered by Trac 0.9.3 By Edgewall Software. Visit the SUMOVER project website at http://www.cs.ucl.ac.uk/research/sumover/ -------------------------------------------------------------------------------- University College London - Gower Street - London - WC1E 6BT - +44 (0)20 7679 2000 - Copyright ? 1999-2006 UCL Disclaimer | Accessibility | Privacy | Advanced Search | Help