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 #include   
38 #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