1 /*encoder-h261.h (c) 1999-2000 Derek J Smithies (dereks@ibm.net)
2 * Indranet Technologies ltd (lara@indranet.co.nz)
4 * This file is derived from vic, http://www-nrg.ee.lbl.gov/vic/
5 * Their copyright notice is below.
8 * Copyright (c) 1993-1995 The Regents of the University of California.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and the Network Research Group at
23 * Lawrence Berkeley Laboratory.
24 * 4. Neither the name of the University nor of the Laboratory may be used
25 * to endorse or promote products derived from this software without
26 * specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 /************ Change log
44 * Revision 1.2 2006/07/31 09:09:21 csoutheren
45 * Checkin of validated codec used during development
47 * Revision 1.1.2.1 2006/04/06 01:17:17 csoutheren
48 * Initial version of H.261 video codec plugin for OPAL
50 * Revision 2.1 2003/03/15 23:42:59 robertj
51 * Update to OpenH323 v1.11.7
53 * Revision 1.12 2002/05/17 01:47:33 dereks
54 * backout the integer maths in the h261 codec.
56 * Revision 1.11 2002/04/26 04:57:41 dereks
57 * Add Walter Whitlocks fixes, based on Victor Ivashim's suggestions to
58 * improve the quality with Netmeeting. Thanks guys!!!!
60 * Revision 1.10 2002/04/05 00:53:19 dereks
61 * Modify video frame encoding so that frame is encoded on an incremental basis.
62 * Thanks to Walter Whitlock - good work.
64 * Revision 1.9 2001/10/16 23:51:42 dereks
65 * Change vic's fdct() from floating-point to fix-point. Improves performance
66 * for h261 video significantly on some machines. Thanks to Cosmos Jiang
68 * Revision 1.8 2001/10/16 21:20:07 yurik
69 * Removed warnings on Windows CE. Submitted by Jehan Bing, jehan@bravobrava.com
71 * Revision 1.6 2001/05/10 05:25:44 robertj
72 * Removed need for VIC code to use ptlib.
74 * Revision 1.5 2000/08/25 03:18:49 dereks
75 * Add change log facility (Thanks Robert for the info on implementation)
81 #include "bsd-endian.h"
85 #include "transmitter.h"
89 * H.261 encapsulation.in payload of h261 packet.
93 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
94 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95 * |SBIT |EBIT |I|V| GOBN | MBAP | QUANT | HMVD | VMVD |
96 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99 // define H261 header related values
100 // (currently these are defined in both p64.h and encoder-h261.h for use
101 // in decode and encode. Should there be one common include file?)
102 typedef unsigned h261hdr_t
;
105 #define CIF_WIDTH 352
106 #define CIF_HEIGHT 288
107 #define QCIF_WIDTH 176
108 #define QCIF_HEIGHT 144
109 #define BMB 6 /* # blocks in a MB */
110 #define MBPERGOB 33 /* # of Macroblocks per GOB */
114 #define BB_INT INT_64
120 #if BYTE_ORDER == LITTLE_ENDIAN
122 #define STORE_BITS(bb, bc) \
123 bc[0] = (u_char)(bb >> 56); \
124 bc[1] = (u_char)(bb >> 48); \
125 bc[2] = (u_char)(bb >> 40); \
126 bc[3] = (u_char)(bb >> 32); \
127 bc[4] = (u_char)(bb >> 24); \
128 bc[5] = (u_char)(bb >> 16); \
129 bc[6] = (u_char)(bb >> 8); \
130 bc[7] = (u_char)(bb);
131 #define LOAD_BITS(bc) \
132 ((BB_INT)bc[0] << 56 | \
133 (BB_INT)bc[1] << 48 | \
134 (BB_INT)bc[2] << 40 | \
135 (BB_INT)bc[3] << 32 | \
136 (BB_INT)bc[4] << 24 | \
137 (BB_INT)bc[5] << 16 | \
138 (BB_INT)bc[6] << 8 | \
141 #define STORE_BITS(bb, bc) \
142 bc[0] = (u_char)(bb >> 24); \
143 bc[1] = (u_char)(bb >> 16); \
144 bc[2] = (u_char)(bb >> 8); \
145 bc[3] = (u_char)(bb);
146 #define LOAD_BITS(bc) (ntohl(*(BB_INT*)(bc)))
149 #define STORE_BITS(bb, bc) *(BB_INT*)bc = (bb);
150 #define LOAD_BITS(bc) (*(BB_INT*)(bc))
153 /** append the "n" LSbits of "bits" to the place pointed to by bc
154 post-increment "bc" as needed. "bb" is used for intermediate storage
155 "nbb" keeps track of bits in "bb"
156 note that ALL bits in "n" are OR'ed into the result
158 #define PUT_BITS(bits, n, nbb, bb, bc) \
162 u_int extra = (nbb) - NBIT; \
163 bb |= (BB_INT)(bits) >> extra; \
165 bc += sizeof(BB_INT); \
166 bb = (BB_INT)(bits) << (NBIT - extra); \
169 bb |= (BB_INT)(bits) << (NBIT - (nbb)); \
173 class H261Encoder
:public Encoder
{
177 int encode(const VideoFrame
*, const u_char
*crvec
);
178 H261Encoder(Transmitter
*T
);
179 virtual ~H261Encoder(void)=0;
180 void encode_blk(const short* blk
, const char* lm
);
181 int flush(Transmitter::pktbuf
* pb
, int nbit
, Transmitter::pktbuf
* npb
);
182 char* make_level_map(int q
, u_int fthresh
);
183 void setquantizers(int lq
, int mq
, int hq
);
185 virtual void SetSize(int /*w*/, int /*h*/){};
186 virtual void encode_mb(u_int
/*mba*/, const u_char
* /*frm*/,
187 u_int
/*loff*/, u_int
/*coff*/, int /*how*/){};
190 BB_INT bb_
; // intermediate working space for encoding bits
191 u_int nbb_
; // # of valid bits in bb_
193 u_char
* bs_
; // used as pointer to start of buffer
194 u_char
* bc_
; // where to put encoded bits in buffer
195 int sbit_
; // SBIT value obtained from previous packet for use on next packet
197 u_char lq_
; /* low quality quantizer */
198 u_char mq_
; /* medium quality quantizer */
199 u_char hq_
; /* high quality quantizer */
200 u_char mquant_
; /* the last quantizer we sent to other side */
201 int quant_required_
; /* 1 if not quant'd in dct */
202 u_int ngob_
; // number of GOBs for this frame size, (3 or 12)
203 u_int mba_
; // address of just encoded macroblock
205 u_int cif_
; /* 1 for CIF, 0 for QCIF */
210 u_int loffsize_
; /* amount of 1 luma block */
211 u_int coffsize_
; /* amount of 1 chroma block */
212 u_int bloffsize_
; /* amount of 1 block advance */
214 const char* llm_
[32]; /* luma dct val -> level maps */
215 const char* clm_
[32]; /* chroma dct val -> level maps */
217 float lqt_
[64]; /* low quality quantizer */
218 float mqt_
[64]; /* medium quality quantizer */
219 float hqt_
[64]; /* high quality quantizer */
221 u_int coff_
[12]; /* where to find U given gob# */
222 u_int loff_
[12]; /* where to find Y given gob# */
223 u_int blkno_
[12]; /* for CR */
225 const VideoFrame
*gVf
; // current video frame YUV data
226 bool gPicture
; // if TRUE, send picture layer header
227 int gHdrGOBN
; // next GOB number for last encoded MB
228 int gNxtGOB
; // GOB number for next marcroblock to be considered for encoding
229 int gGobMax
; // maximum GOB number in frame
230 bool gGOBhdrNxt
; // set TRUE when GOB header is next data
231 bool gSendGOBhdr
; // set TRUE when GOB header must be encoded before next MB
232 int gHdrMBAP
; // address of last macroblock encoded in previous packet 1..33
233 int gNxtMBA
; // address of next macroblock to be considered for encoding
234 int gHdrQUANT
; // QUANT in effect for next MB in buffer
235 int gStep
; // Macro Block step size
236 bool gDone
; // Set TRUE when encoding of frame is done
237 int gDbase
; //offset from gData where valid data starts
238 int gNbytes
; // number of bytes in gData buffer from previous packet
245 class H261DCTEncoder
: public H261Encoder
248 H261DCTEncoder(Transmitter
*T
);
249 int consume(const VideoFrame
*);
250 void SetSize(int w
, int h
);
252 void encode_mb(u_int mba
, const u_char
* frm
,
253 u_int loff
, u_int coff
, int how
);
256 class H261PixelEncoder
: public H261Encoder
259 H261PixelEncoder(Transmitter
*T
);
260 int consume(const VideoFrame
*);
261 void SetSize(int w
, int h
);
262 int PreIncEncodeSetup(const VideoFrame
*);
263 void IncEncodeAndGetPacket(u_char
* buffer
, unsigned & length
);
264 /** When incrementally encoding, return true if there is still
265 more encoding waiting to be done for the current video frame.
267 int MoreToIncEncode()
271 void encode_mb(u_int mba
, const u_char
* frm
,
272 u_int loff
, u_int coff
, int how
);
274 u_char gData
[2 * RTP_MTU
];